在C#/ Winforms中使Web服务方法异步

时间:2009-06-24 01:54:30

标签: c# winforms asynchronous event-handling

让我们说我正在调用一些我无法控制的Web服务方法。这种方法需要很长时间才能运行,而开发Web服务的人并不认为包含异步版本。

在C#/ winforms中为这种方法创建异步包装的最佳方法是什么?

目前我正在使用ThreadPool运行webservice方法,然后在webservice完成时调用事件。这样的事情。

DoWorkAsync() {
    Webservice.LongMethod()
    WorkCompleteEvent()
}

然而,这似乎并不理想。例如,如果我尝试从事件处理程序修改表单控件,我会收到一条警告,告知不要从其他线程等那样做。

有没有人有任何其他建议来解决这个问题?

3 个答案:

答案 0 :(得分:6)

请参阅How to: Make Thread-Safe Calls to Windows Forms Controls上的MSDN文章&还有Jon Skeet很棒guide to threading更具体Threading in Windows Forms

引用Jon(强调我的):

  

永远不要在除 Invoke BeginInvoke EndInvoke CreateGraphics <之外的其他线程上创建的控件上调用任何方法或属性/ em>和 InvokeRequired 。   每个控件都有效地绑定到运行其消息泵的线程。 如果您尝试从其他线程访问或更改UI中的任何内容(例如更改Text属性),则可能会以其他方式冒着程序挂起或行为不当的风险。您可能会侥幸逃脱在某些情况下,但只有盲目的运气。 幸运的是,已经提供了Invoke,BeginInvoke和EndInvoke方法,以便您可以要求UI线程以安全的方式为您调用方法。

答案 1 :(得分:1)

解决方案是使用内置的Web服务异步解决方案。使用webservice.BeginLongMethod()来调用和使用IAsyncResult。但请记住,您必须始终使用Invoke方法来更新Windows窗体代码,因为它位于不同的线程上。

参见以下文章

http://www.informit.com/articles/article.aspx?p=29395&seqNum=4

http://msdn.microsoft.com/en-us/library/ms228972.aspx

答案 2 :(得分:-1)

您可以使用异步委托来调用Web方法。 您可以查看Asynchronous File Copy/Move in C#以了解如何完成此操作。考虑FileCopy是您的Web方法(而不是如图所示的类方法)

对于跨线程错误,您可以参考crossthread operations error