简体   繁体   English

使Webservice方法在C#/ Winforms中异步

[英]Making a Webservice Method Asynchronous in C#/Winforms

Lets say I am calling some web service method that I do not control. 可以说我正在调用一些我无法控制的Web服务方法。 This method takes a long time to run, and whoever developed the web service did not think to include a asynchronous version. 此方法需要花费很长时间才能运行,并且开发Web服务的任何人都认为没有异步版本。

What is the best way to create an asynchronous wrapper for such a method in C#/winforms? 在C#/ winforms中为此类方法创建异步包装的最佳方法是什么?

At the moment I am using a ThreadPool to run the webservice method and then calling an event when the webservice finishes. 目前,我正在使用ThreadPool运行webservice方法,然后在webservice完成时调用一个事件。 Something like this. 这样的事情。

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

However, this doesn't appear to be ideal. 但是,这似乎并不理想。 For example, if I try to modify the form controls from the event handler I get a warning about not doing that from a different thread etc. 例如,如果我尝试从事件处理程序修改表单控件,则会收到有关不从其他线程执行此操作的警告。

Does anyone have any other suggestions for solving this problem? 有人有其他解决此问题的建议吗?

See the MSDN article on How to: Make Thread-Safe Calls to Windows Forms Controls & also Jon Skeet's great guide to threading more specifically Threading in Windows Forms . 请参阅有关如何:对Windows Forms控件进行线程安全调用的MSDN文章,以及Jon Skeet的关于如何 在Windows Forms中 进行线程化的出色指南

Quoting Jon (emphasis mine): 引用乔恩(重点是我的):

Never invoke any method or property on a control created on another thread other than Invoke , BeginInvoke , EndInvoke or CreateGraphics , and InvokeRequired . InvokeBeginInvokeEndInvokeCreateGraphicsInvokeRequired之外,不要在另一个线程上创建的控件上调用任何方法或属性。 Each control is effectively bound to a thread which runs its message pump. 每个控件都有效地绑定到运行其消息泵的线程。 If you try to access or change anything in the UI (for example changing the Text property) from a different thread, you run a risk of your program hanging or misbehaving in other ways. 如果尝试从其他线程访问或更改UI中的任何内容(例如更改Text属性),则可能会导致程序挂起或行为异常。 You may get away with it in some cases, but only by blind luck. 在某些情况下,您可能会摆脱它,但是只能靠运气。 Fortunately, the Invoke, BeginInvoke and EndInvoke methods have been provided so that you can ask the UI thread to call a method for you in a safe manner. 幸运的是,已经提供了Invoke,BeginInvoke和EndInvoke方法,以便您可以要求UI线程以安全的方式为您调用方法。

The solution is to use built in asynchronous solution to the web services. 该解决方案是对Web服务使用内置的异步解决方案。 Use the webservice.BeginLongMethod() to call and use the IAsyncResult. 使用webservice.BeginLongMethod()调用并使用IAsyncResult。 But remember that you must always use Invoke methods to update windows forms code since it is on a different thread. 但是请记住,由于它位于不同的线程上,因此必须始终使用Invoke方法来更新Windows窗体代码。

See following articles 请参阅以下文章

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

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

You can use asynchronous delegates to call the web method. 您可以使用异步委托来调用Web方法。 You can have a look at Asynchronous File Copy/Move in C# to see how it can be done. 您可以查看C#中的“ 异步文件复制/移动”以了解如何完成。 Consider FileCopy is your web method (rather than a class method as shown in the eg.) 考虑使用FileCopy是您的Web方法(而不是如示例所示的类方法)。

For cross-thread errors you can refer to crossthread operations error 对于跨线程错误,您可以参考跨线程操作错误

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM