有没有办法在WP8 / Silverlight中调用Async方法时传递回调

时间:2012-11-22 08:08:12

标签: c# .net silverlight windows-8 windows-phone-8

我一直在编写调用SOAP Web服务后端的Windows Phone 8代码。根据我的阅读,典型的模式是:

var client = new KitchenPCSoapClient();

client.LogonCompleted += client_LogonCompleted;
client.LogonAsync(username, password);

对我而言,这似乎与直觉相反。如果我使用同一个客户端多次调用LogonAsync,我不一定希望每次都使用相同的LogonCompleted回调。

我想要的是一个更像JavaScript的模式,您可以在其中传递对回调函数的引用。更像是:

var client = new KitchenPCSoapClient();
client.LogonAsync(username, password, client_LogonCompleted);

有没有办法实现这样的模式,或者我应该强迫自己习惯于在调用LogonCompleted之前设置LogonAsync属性,或者设置userState属性我想区分不同的背景?

2 个答案:

答案 0 :(得分:0)

您可以使用Dispatcher并在UI端调用该函数...

我这样做

回调函数

private void AddPricesHandler(CompletedEventArgs response, Exception e)
{
  //your code gose here
}

调用代理calss函数

Proxy.AddData(AddPricesHandler, request);

代理类调用webservice

public void AddData(Action<CompletedEventArgs, Exception> callback, IPVWorkflowService.CreateEditDeletePriceSourceRequest request)
        {
            _workflowProxy.CreateEditDeletePriceSourceAsync(request, callback);
            _workflowProxy.CreateEditDeletePriceSourceCompleted+=new EventHandler<CreateEditDeletePriceSourceCompletedEventArgs>(_workflowProxy_CreateEditDeletePriceSourceCompleted); 
        }

完成函数使用调度程序来调用回调函数

    void _workflowProxy_CreateEditDeletePriceSourceCompleted(object sender, CreateEditDeletePriceSourceCompletedEventArgs e)
    {
        try
        {
            this.dispatcher.BeginInvoke((Action)(() =>
            {
                (e.UserState as Action<CompletedEventArgs, Exception>)(e, null);
            }));
        }
        catch (Exception ex)
        {
            this.dispatcher.BeginInvoke((Action)(() =>
            {
                (e.UserState as Action<CompletedEventArgs, Exception>)(e, ex);
            }));
        }
        finally
        {
            _workflowProxy.CreateEditDeletePriceSourceCompleted -= _workflowProxy_CreateEditDeletePriceSourceCompleted;
            _workflowProxy = null;
        }
    }

答案 1 :(得分:0)

Async / Await的优点在于您不必编写回调,只需编写看起来像同步的代码,但在后台它是异步执行的:

var client = new KitchenPCSoapClient();
await client.LogonAsync(username, password);

// you get here after the async logon is completed
// do stuff after logon

但是如果你真的想使用回调,你可以在Task对象上使用ContinueWith方法,该方法是从异步方法返回的:

var client = new KitchenPCSoapClient();
Task task = client.LogonAsync(username, password);

// this method is called when async execution of task is finished
task.ContinueWith(client_LogonCompleted);