C#:我如何优雅地或简单地进行交叉线程调用?

时间:2009-03-06 07:41:33

标签: c# visual-studio-2008

我有一个tcp服务器,当客户端连接时,它创建一个新线程并将它们添加到它,但每次我尝试访问有关连接的信息或任何有关它的信息时,甚至要记住有多少客户端是连接,我得到一个跨线程的非法例外或类似的东西。

我已经阅读了几个关于委托,调用和反射的教程,但是所有的例子或教程都让我感到困惑,因为在另一个方面调用某种方式会失败。

有一种优雅或简单的方式吗?我是否需要先学习如何做其他事情?或者我只是让事情比他们更复杂?任何建议,链接或提示都是最受欢迎和接受的。

4 个答案:

答案 0 :(得分:1)

我想你是从客户端连接线程直接进入UI的。这个不好。相反,请考虑使用MVP模式的某些变体来将表示逻辑与视图分离。因此,您的“连接线程”将与某些中间人交谈,主持人将与同一中间人交谈,只需交出一些数据进行查看即可显示。

就跨线程操作而言,特别是UI线程操作,当你想要将非UI线程的调用编组到UI线程时,我发现SynchronizationContext在cicrumstance中非常有用。有关更深入的讨论,请参阅this article

答案 1 :(得分:0)

使用委托事件

那将是我最好的答案。

http://www.codeproject.com/KB/cs/Cross_thread_Events.aspx

答案 2 :(得分:0)

网上有很多例子可以帮助您: http://www.google.com/search?q=tcp+server+multi+thread

使用C#时,Concurrency and Coordination Runtime (CCR)也有一个关于实现多线程tcp服务器的示例。 CCR允许更好的范例来实现并行处理,它简化了许多标准的多线程代码。

答案 3 :(得分:0)

我猜你得到这个跨线程异常,因为你试图从线程代码更新屏幕元素。如果您需要这样做,您可以使用匿名方法获得一个简单的解决方案。

假设您要将项目添加到名为ListBoxLog的列表框中。这段代码可以从任何线程中解决问题:

ListBoxLog.Invoke((MethodInvoker)delegate { ListBoxLog.Items.Add("Done"); });

还有一个要检查的属性.InvokeRequired你可以检查调用是否是nessecary。您通常会检查可以由主UI线程和任何后台线程调用的函数中的该属性。

您也可以像使用Invoke一样使用BeginInvoke。 BeginInvoke完全是异步的,不会等待委托中的代码完成。