2014-09-19 53 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