基于UI的应用程序使用基于事件的异步模式

时间:2015-04-10 15:14:25

标签: c#

我已根据Microsoft的基于事件的异步模式实现了一个组件,以便与我想在基于UI的应用程序中使用的REST服务进行交互。

我会发布代码,但有很多。

无论如何,我简要观察的是:

  1. 我启动我的应用程序,它在ThreadID 1上运行,因此UI属于ThreadID 1
  2. 我在组件中注册了一个方法,当taskCompleted事件触发(仍在ThreadID 1上运行)时,该组件会更新我的UI
  3. 我调用runTaskAsync方法,该方法使用AsyncOperationManager创建AsyncOperation,如本文所述,并调用其BeginInvoke方法。
  4. 在调用BeginInvoke之后,执行从ThreadID 1切换到ThreadID 5(或任何)并进入工作方法
  5. 通过ThreadID 5完成工作后,将调用AsyncOperation.PostOperationCompleted方法,并且执行将切换到另一个ThreadID 7(或任何),而不是返回到ThreadID 1。
  6. 问题是UI更新方法是由不拥有UI的第三个线程(ID 7)执行的。

    在我的解决方法中,我检查了this.InvokeRequired属性:

    private void task_completed(EventArgs e)
    {
        if (this.InvokeRequired)
        {
            this.BeginInvoke(new Action<EventArgs>(login_completed), new[] { e });
        }
        else
        {
            //Execute UI stuff             
        }
    }
    

    它工作正常,但我想知道我是否犯了错误,或者这种行为是否正常。

    我希望AsyncOperation.PostOperationCompleted方法直接调用ThreadID 1。相反,它创建了另一个必须调用线程1 ...

    的线程

    如果它直接调用线程1会很好。

    感谢阅读。

1 个答案:

答案 0 :(得分:0)

在幕后,AsyncOperation.PostOperationCompleted()调用Post,最终执行此操作(根据Reflector,使用.NET 4.5):

ThreadPool.QueueUserWorkItem(new WaitCallback(d.Invoke), state);

其中d是你的回调代表。

所以你的委托正在线程池的一个线程上运行。

你所看到的是正常的。