在我使用WPF和C#构建的.NET应用程序中,我使用AsyncMethodCaller调用异步函数。在回调中,我想更新GUI中的一些数据,但我不允许这样做,因为这是主线程所拥有的。我该怎么办?
处理此问题的常见推荐方法是什么?
给出的运行时错误是:
调用线程无法访问此对象,因为另一个线程拥有它。
答案 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;
}