开发者

Async function - callback using object owned by main thread

开发者 https://www.devze.com 2022-12-14 05:14 出处:网络
In my .NET application built with WPF and C# I call an async function using AsyncMethodCaller. In the callback I\'d like to update some data in the GUI, but I\'m not allowed to as this is owned by the

In my .NET application built with WPF and C# I call an async function using AsyncMethodCaller. In the callback I'd like to update some data in the GUI, but I'm not allowed to as this is owned by the main thread. How to I do it?

  • Invoke an update on the main thread? How?
  • Pass an object (e.g. ViewModel) as state to the callback and update data on this - which again is bound to the GUI?
  • Some other way?

What's the common, recommended way of handling this?

The runtime error 开发者_开发知识库given is:

The calling thread cannot access this object because a different thread owns it.


You need to invoke the method using the Dispatcher, calling Dispatcher.Invoke method. This MSDN article explains how to update UI in WPF from asynchronous operations in great detail.


Bambuska,

Using Dispatcher is really a lot easier than you think. Please take a look at my code:

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");    
        }    
    }    
}  

This should work (it does in my case). Anyway, please keep me informed.


I tried passing the ViewModel object as asyncState such that the callback can access this object. The callback will typically update some property with a value received from the async function call. The ViewModel will eventually be where I want to do the status update anyway. Is this a proper way of handling it? Or should I always use Dispatcher.Invoke?

The ViewModel:

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

Calling the function:

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

The callback updates the 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; 
}
0

精彩评论

暂无评论...
验证码 换一张
取 消