2010-06-16 39 views
10

我想從Silverlight(4)調用一個Rpc到JBOSS webserver的原型。我編寫了代碼,它正在控制檯應用程序中工作 - 所以我知道Jboss正在響應Web請求。它移植到Silverlight 4中,導致問題出現:Silverlight HttpWebRequest.Create掛在異步塊內

let uri = new Uri(queryUrl) 
// this is the line that hangs 
let request : HttpWebRequest = downcast WebRequest.Create(uri) 
request.Method <- httpMethod; 
request.ContentType <- contentType 

它可能是一個沙箱的問題,因爲我的Silverlight是正在擔任了我的文件系統和URI是到本地主機的引用 - 雖然我不是連得到一個例外。思考?

THX


更新1

我創建了一個新的項目,並在移植我的代碼,現在它是工作;對於F#Silverlight集成仍然存在一些問題。還是想知道關於調試「掛」在網上的舊模式創建的想法...


更新2

let uri = Uri("http://localhost./portal/main?isSecure=IbongAdarnaNiFranciscoBalagtas") 
// this WebRequest.Create works fine 
let req : HttpWebRequest = downcast WebRequest.Create(uri) 

let Login = async { 
    let uri = new Uri("http://localhost/portal/main?isSecure=IbongAdarnaNiFranciscoBalagtas") 
    // code hangs on this WebRequest.Create 
    let request : HttpWebRequest = downcast WebRequest.Create(uri) 
    return request 
} 
Login |> Async.RunSynchronously 

我必須失去了一些東西; Async模塊在控制檯應用程序中正常工作 - 是否在Silverlight應用程序中不允許?

+0

是否有這樣的一個更新 - 你得到它的工作... – akaphenom 2010-06-21 15:44:31

回答

5

(感謝發送這fsbugs,迫使我們採取強硬的樣子)。

問題是Async.RunSynchronously。當在UI線程上調用時,這會阻塞UI線程。事實證明,Silverlight上的WebRequest.Create()調度到UI線程。所以這是一個僵局。

一般來說,儘量避免在Silverlight(或任何UI線程)上使用Async.RunSynchronously。在本例中,您可以使用Async.StartImmediate。或者,我認爲你可以從任何後臺線程調用RunSynchronously沒有問題。 (我沒試過足夠的終端到終端的Silverlight的情況下自己提供更多的意見,但你可以看看

Game programming in F# (with Silverlight and WPF)

F# and Silverlight

F# async on the client side

了短短的例子。 )回想起來,F#設計團隊認爲我們可能不應該在FSharp.Core for Silverlight中包含Async.RunSynchronously;方法的潛力這違反了平臺的精神(沒有攔截呼叫)。在將來的Silverlight版本中,我們可能會棄用這種方法。另一方面,它在Silverlight上仍然具有CPU密集型並行性的有效用途,例如,在後臺線程上並行運行(非IO)代碼。)

0

我有類似的問題。我正在製作一個Silverlight MVVM ViewModel來綁定來自web的數據。 唐賽姆評價自己:

我不是一個數據綁定專家,但我相信 你不能「躲」在這樣的視圖模型爲WPF和Silverlight的 的asyncness 。我想你需要 公開任務,異步或 可觀察的集合。 AFAIK唯一的 方式讓Silverlight和WPF綁定 異步地屬性是如果它 是一個可觀察的集合。

無論如何,我安裝了F#Power Pack以獲取AsyncReadToEnd。 它沒有解決這個問題......我將域添加到受信任的站點,但它沒有幫助...然後我添加了MySolution.Web -asp.net站點和clientaccesspolicy.xml。我不知道這些是否有影響。現在

,與Async.StartImmediate我得到了Web服務調用的工作:

let mutable callresult = "" 
//let event = new Event<string>() 
//let eventvalue = event.Publish 
let internal fetch (url : Uri) trigger = 
    let req = WebRequest.CreateHttp url 
    //req.CookieContainer <- new CookieContainer() 
    let asynccall = 
     async{ 
      try 
       let! res = req.AsyncGetResponse() 
       use stream = res.GetResponseStream() 
       use reader = new StreamReader(stream) 
       let! txt = reader.AsyncReadToEnd() 
       //event.Trigger(txt) 
       callresult <- txt //I had some processing here... 
       trigger "" |> ignore 
      with 
       | :? System.Exception as ex -> 
        failwith(ex.ToString()) //just for debug 
     } 
    asynccall |> Async.StartImmediate 

現在,我需要我的視圖模型,聽取了可變callresult。 在你的情況下,你還需要一個crossdomain.xml到服務器。

扳機需要使用UI線程:

let trigger _ = 
    let update _ = x.myViewModelProperty <- callresult 
    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(new Action(update)) |> ignore 
fetch serviceUrl trigger