如何在dispatcher.begininvoke上正确调用回调?

时间:2015-05-28 21:15:59

标签: c# dispatcher

我认为我可以打电话

var dispatcherOp = Application.Current.Dispatcher.BeginInvoke(Action());
dispatcherOp.Completed += dispatcherOp_Completed;

然后我有点担心。如果begininvoke是异步的,那么什么阻止调度程序在我得到返回的调度程序操作并附加到已完成的事件之前完成操作。

我认为这一定是不可能的,但如果是这样,我想知道原因。

4 个答案:

答案 0 :(得分:3)

你是对的;这不安全。您应该只是await操作。

答案 1 :(得分:1)

答案是:没有。

有三种可能的方法:

1。)您可以决定等待执行操作并不重要。如果是,那么您选择fire and forget策略。

2。)您可以决定是否需要同步请求,等待SLaks建议。

3.。)您可以将请求保持为异步,但请使用callback

答案 2 :(得分:0)

不幸的是,Dispatcher没有begininvoke所需的回调函数。

我的程序中不需要同步操作,但我在谷歌搜索或两次搜索后意识到我可以像这样锁定它

lock (this)
            {
                var dispatcherOp = Application.Current.Dispatcher.BeginInvoke(MyAction, DispatcherPriority.Normal);
                dispatcherOp.Completed += dispatcherOp_Completed;
            }



void dispatcherOp_Completed(object sender, EventArgs e)
        {
            lock (this)
            {

            }

        }

然后再次锁定已完成函数中的同一对象,以便在您完成附加处理程序之前调度程序无法完成。

答案 3 :(得分:0)

在现代应用程序中使用Dispatcher.BeginInvoke是没有理由的。

如果您的代码为后台操作建模,则使用async / awaitIProgress<T>进行任何进度更新。

如果您的代码为异步序列建模,则使用带有ObserveOn的Rx(Reactive Extensions)来更新具有UI线程关联的对象。