2009-03-06 55 views
3

我有一个tcp服务器,当一个客户端连接时,它会创建一个新线程并将它添加到它,但是每次我尝试访问有关连接的信息或任何有关它的信息时,即使保持有多少客户端连接,我得到了一个跨线程非法异常或类似的东西。C#:我如何优雅地或简单地进行交叉线程调用?

我读过几个关于代理,调用和反射的教程,但所有的例子或教程都让我困惑,因为做某个调用的方式失败了。

有没有这样做的优雅或简单的方法?我是否需要学习如何首先做其他事情?还是我只是让事情比他们更复杂?任何建议,链接或提示最受赞赏和接受。

回答

0

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

假设您想要将一个项目添加到名为ListBoxLog的列表框中。此代码会从任何线程做的伎俩:

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

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

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

0

使用代表事件

这将是我最好的答案。

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

+0

其次CodeProject文章,尽管我更喜欢BackgroundWorker解决方案(也在文章中)。但是,在许多情况下,异步调用事件是很好的。 – OregonGhost 2009-03-06 07:47:50

+0

我必须承认我对BackgroundWorker类没有太多的工作,但我会着眼于此。谢谢。 – 2009-03-06 07:51:30

1

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

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