异步函数 - 使用主线程拥有的对象进行回调

时间:2009-12-15 10:13:11

标签: c# .net wpf multithreading asynchronous

在我使用WPF和C#构建的.NET应用程序中,我使用AsyncMethodCaller调用异步函数。在回调中,我想更新GUI中的一些数据,但我不允许这样做,因为这是主线程所拥有的。我该怎么办?

  • 在主线程上调用更新?怎么样?
  • 将一个对象(例如ViewModel)作为状态传递给回调并更新数据 - 它再次绑定到GUI?
  • 其他一些方式?

处理此问题的常见推荐方法是什么?

给出的运行时错误是:

  

调用线程无法访问此对象,因为另一个线程拥有它。

3 个答案:

答案 0 :(得分:3)

您需要使用Dispatcher调用该方法,并调用Dispatcher.Invoke方法。 这个MSDN article解释了如何非常详细地从异步操作更新WPF中的UI。

答案 1 :(得分:2)

Bambuska,

使用Dispatcher比你想象的要容易得多。请看一下我的代码:

public class MyViewModel : BaseViewModel    
{    
    public int Result    
    {    
        get { return _result; }    
        set    
        {    
            _result = value;     

            Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new WorkMethod(delegate
                {
                    this._result = SampleMethodChangingResult();
                }));

            this.RaisePropertyChanged("Result");    
        }    
    }    
}  

这应该有效(在我的情况下确实如此)。无论如何,请通知我。

答案 2 :(得分:0)

我尝试将ViewModel对象作为asyncState传递,以便回调可以访问此对象。回调通常会使用从异步函数调用接收的值更新某些属性。 ViewModel最终将成为我想要进行状态更新的地方。这是处理它的正确方法吗?或者我应该总是使用Dispatcher.Invoke?

ViewModel:

public class MyViewModel : BaseViewModel
{
    public int Result
    {
        get { return _result; }
        set
        {
            _result = value; 
            this.RaisePropertyChanged("Result");
        }
    }
}

调用该函数:

caller.BeginInvoke(num1, num2, new AsyncCallback(CallbackMethod), _myViewModel);

回调更新了viewmodel:

private void CallbackMethod(IAsyncResult ar)
{
    var result = (AsyncResult)ar;
    var caller = (AsyncMethodCaller)result.AsyncDelegate;
    var vm = ar.AsyncState as MyViewModel;
    int returnValue = caller.EndInvoke(ar);
    vm.Result = returnValue; 
}