【问题标题】:Making a Webservice Method Asynchronous in C#/Winforms在 C#/Winforms 中使 Web 服务方法异步
【发布时间】:2009-06-24 01:54:30
【问题描述】:

假设我正在调用一些我无法控制的 Web 服务方法。这种方法需要很长时间才能运行,而且开发 Web 服务的人也没有想到要包含异步版本。

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

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

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

但是,这似乎并不理想。例如,如果我尝试从事件处理程序修改表单控件,我会收到一条警告,提示我不要从其他线程等执行此操作。

有没有人有其他解决这个问题的建议?

【问题讨论】:

    标签: c# winforms asynchronous event-handling


    【解决方案1】:

    请参阅 How to: Make Thread-Safe Calls to Windows Forms Controls 上的 MSDN 文章以及 Jon Skeet 的出色 guide to threading,更具体地说是 Threading in Windows Forms

    引用 Jon(强调我的):

    永远不要调用在另一个线程上创建的控件上的任何方法或属性,除了 InvokeBeginInvokeEndInvokeCreateGraphics 和 InvokeRequired。 每个控件都有效地绑定到运行其消息泵的线程。 如果您尝试从不同的线程访问或更改 UI 中的任何内容(例如更改 Text 属性),您将面临程序挂起或以其他方式出现异常的风险。您可能会侥幸逃脱在某些情况下,但只能靠运气。 幸运的是,已经提供了 Invoke、BeginInvoke 和 EndInvoke 方法,以便您可以要求 UI 线程以安全的方式为您调用方法。

    【讨论】:

      【解决方案2】:

      解决方案是对 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

      【讨论】:

        【解决方案3】:

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

        跨线程错误可以参考crossthread operations error

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-10-23
          • 2011-08-28
          • 2013-08-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多