2014-09-19 92 views
1

我在UI上遇到跨線程問題。我已經閱讀了所有的方法來實現它,並且已經實現了它們,如下所示。跨線程UI

public void UpdateList(object obj) 
    { 
     // do we need to switch threads? 
     if (listBox1.InvokeRequired) 
     { 
      MethodInvoker del =() => UpdateList(obj); 
      this.Invoke(del); 
      return; 
     } 
     // ok so now we're here, this means we're able to update the control 
     // so we unbox the object into a string 
     string text = (string)obj; 
     // and update 
     listBox1.Items.Add(text); 
    } 

問題是當我嘗試做一個

hubConnection.Start().Wait(); 

該呼叫我試圖更新我的列表之後。

沒有等待很好。當我添加Wait時,它掛在UpdateList Invoke上。沒有錯誤......它只是掛起。

我在按鈕事件中處理此調用。

+0

hubConnection.Start()。等待()創建主線程死鎖。刪除等待和看到 – lboshuizen 2014-09-19 15:51:40

+0

簡單的規則要記住:使用調用錯誤99%,總是使用BeginInvoke。開始一個線程並等待它是100%錯誤,根本不需要線程。使用InvokeRequired是95%錯誤,你已經知道它是從一個線程調用的。把它們寫下來,釘在牆上,讓你擺脫困境。 – 2014-09-20 11:48:42

回答

-1

您已經生成了一個遞歸循環。假設需要調用,您將調用相同的方法,再次點擊if (listBox1.InvokeRequired)(仍然會傳遞true),並開始循環,因爲您一次又一次地調用相同的方法。這是更好地在這裏做一個的if..else模式,你直接調用的ListBox中的變化或者乾脆不調用執行更改

一個例子

if (listBox1.InvokeRequired) 
    { 
     listBox1.Invoke(()=> { listBox1.Items.Add((string)text) }; 
    } 
    else 
    { 
     string text = (string)obj; 
     // and update 
     listBox1.Items.Add(text); 
    } 
+2

調用調用將執行傳輸到主線程。當updatelist被第二次調用時,InvokeRequired將返回false ==>遞歸結束 – lboshuizen 2014-09-19 16:11:00

1

等待()是創建在一個僵局mainthread。

更換hubconnection.Start.Wait()用:

異步方法等待hubconnection.Start():

public void async StartHubClickedEvent(...){ 
    await hubconnection.Start() 
} 

The Microsoft Async library使上.NET 4.0和VS12使用異步/ awaut的。

Install-Package Microsoft.Bcl.Async 

Deadlock when thread uses dispatcher and the main thread is waiting for thread to finish

+0

我的代碼是Net 4.0。 – Jeff 2014-09-19 17:12:53

+0

更新了我對.net 4的回答 – lboshuizen 2014-09-20 10:18:45