2010-02-03 41 views
3

此代碼導致silverlight掛起。如果我刪除ManualResetEvent的代碼,什麼都不會發生Silverlight異步API的原因掛起和無響應

 private ManualResetEvent mre = new ManualResetEvent(false); 

     ... 

     WebClient sender = new WebClient(); 
     sender. += new OpenReadCompletedEventHandler(this.ReadComplete); 
     sender.OpenReadAsync(new Uri(this.url+"?blob="+BODY, UriKind.Relative)); 

     mre.WaitOne(); 

    } 
    public bool T = false; 
    public void ReadComplete(object sender, OpenReadCompletedEventArgs e) 
    { 

     mre.Set(); 
    } 
+0

它很難放在一起在這個問題上反應靈敏,它缺乏細節。你在下載什麼?下載時你在做什麼? – AnthonyWJones 2010-02-03 18:05:35

+0

沒有什麼真正的下載 – 2010-02-03 21:04:59

回答

2

不能在UI線程(參見「mre.WaitOne」)塊。如果你絕對需要這個WaitOne,你必須在一個單獨的線程中運行你的代碼。這可以做到如下:

var t = new Thread(delegate() 
{ 
    //... 
    mre.WaitOne(); 
    //... 
}); 

人們會期望在回調中的「mre.Set()」將被觸發。但是,我遇到了同樣的問題,顯然,OpenReadAsync回調機制使用UI線程作爲中間調度程序。該調度不能發生,它正在等待事件被設置。

+0

好吧,我現在使用線程,ui不會掛起,但仍然沒有webclient連接,ui不更新,當我調試它時顯示沒有例外... ..怎麼了? – 2010-02-03 17:27:43

+0

「ui不更新」:當我看到這個症狀時,問題是在執行Application.UnhandledException時忽略了異常。將Debugger.Break()調用可能會有所幫助。 – 2010-02-04 07:53:34

+0

你得到ReadComplete()回調嗎? – 2010-02-04 07:55:39

0

只有幾個原因,我可以看到,可能會導致你相信你需要這個阻止等待。或者您不知道應該在完整事件中繼續使用您的代碼,或者您有其他本地狀態,說明ReadCompleted過程無法訪問您沒有包含在示例代碼中。

下面是用於處理下載的流一些鍋爐板代碼: -

string dummy = "Some value"; // local value you still need to access when download complete 

WebClient wc = new WebClient(); 
wc.OpenReadCompleted += (s, args) 
{ 
    if (!args.Cancelled) 
    { 
    try 
    { 
     Stream stream = args.Stream; // This is the data you are after 
     // Do stuff with stream, note the dummy variable is still accessible here. 
    } 
    catch (Exception err) 
    { 
     //Do something sensible with the exception to make sure its surfaced 
    } 
    } 
}; 
sender.OpenReadAsync(new Uri(this.url+"?blob="+BODY, UriKind.Relative));