2013-02-10 45 views
0

我想出了關於如何僞造同步調用的SL WCF支持的想法。Silverlight中的異步回調線程鎖WCF

基本上,

private _completed; 
private IList<Customer> _customers; 
public void IList<Customer> GetAllCustomers() 
{ 
    bool completed = false; 
    DataServiceQuery<Customer> myQuery = this.Context.Customers; 
    myQuery.BeginExecute(OnQueryExecuted, myQuery); 

    while (!_completed) 
     System.Threading.Thread.Sleep(67); //tried join also 

    return _customers; 
} 

private void OnQueryExecuted(IAsyncResult result) 
{ 
    var query = result.AsyncState as DataServiceQuery<Customer>; 
    _customers = query.EndExecute(result).ToList(); 
    _isCompleted = true; 
} 

什麼情況是,這個循環永遠。

我在while循環中放置了一個斷點,將它移出並恢復執行,並在接下來的毫秒中得出結果。

於是,我想到了回調查詢接收結果被排隊到相同的線程查詢在調用。

SL似乎很有決心保持這種行爲,所以即使我換了myQuery.BeginExecute在一個新的線程中,我仍然會得到相同的行爲。

/*編輯:實際上,考慮一下,它會在等待的ui線程上排隊回調。這也是我們得到結果時不需要Dispatcher.Invoke的原因。無論如何,我總是可以在專用線程中完成整個操作(需要等待),然後在那裏等待,但是這需要一堆重構,避免嘗試這一點。 */

有沒有辦法解決這個問題?

+0

你正在以某種方式阻止UI線程,而不是循環爲什麼不只是調用'Execute'?這個方法'GetAllCustomers'永遠不會以你現在擁有的形式進行異步操作,所以只需調用'Execute'。我不明白爲什麼你試圖參與第二個線程而不是阻塞一個線程 - 這沒有任何好處,並且會降低應用程序的性能。你能再詳細一點嗎? – user1416420 2013-02-10 02:09:11

+0

重點是它不是異步的。由於'myQuery.BeginExecute',db調用是異步的。無論如何,如果我調用'Execute',Silverlight突然通知我它不支持同步查詢。 – 2013-02-10 02:11:56

+0

哦,我明白了,我不知道,讓我看看.. – user1416420 2013-02-10 02:12:56

回答

1

這個問題的原因在於EndExecute方法編組到UI線程,但是您用Sleep調用阻塞了UI線程。使用什麼技術阻塞線程並不重要,因爲在UI線程中調用該方法會導致死鎖。

在SIlverlight環境下開發時,您需要能夠異步編程,而不是使用同步方法。如果您使用的是C#5.0,則可以使用異步/等待功能,該功能允許您編寫顯示爲同步的異步代碼,但它將被編譯爲利用回調/延續的異步調用,這是您需要執行的操作您尚未升級到該版本。

+0

因此,如果他們允許在Win應用程序中阻塞UI線程,爲什麼不在SL中?畢竟,你會測試,如果有東西掛起,你會做異步。無論如何,這些事情都會在100毫秒以內迴歸。這不僅僅是將所有東西都作爲延續的問題,現在我必須對一些事情進行併發檢查。如果用戶點擊刷新一些數據列表,那麼我應該禁止從它加載元素,直到它回來..等'async/await'很好,但不能解決這個問題。 – 2013-02-10 11:49:43

+0

我得到了什麼?零!我也可以限制等待133ms,聲明服務器沒有響應,並向用戶顯示錯誤。對於小型往返。像任何理智的人一樣,我會做更大的異步。但是,好吧,讓過去的人過去,現在讓我們在任何地方和任何地方做我們所有的db行程異步。 – 2013-02-10 11:54:13

+0

@ h.alex問題在於阻塞UI線程會凍結整個應用程序。您可以防止執行繪畫事件,阻止用戶移動瀏覽器,阻止他們導航或切換標籤頁。這對用戶體驗非常不利。 – Servy 2013-02-10 17:32:49