2015-12-09 41 views
2

虽然代码是使用Xamarin iOS编写的,但这是一个C#问题。我想知道如何将Task方法与异步函数和回调委托相结合。所以在下面的代码示例中,我想调用await ExecuteGetAsync()并等待SendAsynchronousRequest()完成。组合任务等待委托

private async Task<CustomHttpResponse> ExecuteGetAsync(CustomHttpRequest inRequest) 
{ 
    NSUrlConnection 
     .SendAsynchronousRequest(
      (NSUrlRequest)request, 
      NSOperationQueue.MainQueue, 
      delegate(NSUrlResponse inResponse, NSData inData, NSError inError) 
      { 
       // Return the response somehow 
      }); 
} 
+1

MSDN具有[一篇文章](https://msdn.microsoft.com/en-us/library/hh873178(v = vs.110).aspx)将一种异步模式转换为另一种模式。 – chris

回答

-1

因为您可以访问父范围,所以您可以预先定义结果变量。然后,创建一个等待句柄。当你的代码得到最终响应时,你设置结果和句柄,你的代码返回主范围内的结果。

private async Task<CustomHttpResponse> ExecuteGetAsync(CustomHttpRequest inRequest) 
{ 
    CustomHttpResponse result = null; // Put initial result here. 
    var handle = new AutoResetEvent(false); 
    NSUrlConnection 
     .SendAsynchronousRequest(
      (NSUrlRequest)request, 
      NSOperationQueue.MainQueue, 
      delegate(NSUrlResponse inResponse, NSData inData, NSError inError) 
      { 
       // Return the response somehow 
       result = // make your result 
       handle.Set(); 
      }); 

    handle.WaitOne(10000) // Wait up to 10 seconds for result 
    return result; 
} 
+1

由于您正在同步等待,因此这种情况下的ExecuteGetAsync方法不再是异步的。 –

1

您应该使用TaskCompletionSource类是这样的:

private Task<CustomHttpResponse> ExecuteGetAsync(CustomHttpRequest inRequest) 
{ 
    var tcs = new TaskCompletionSource<CustomHttpResponse>(); 

    NSUrlConnection 
     .SendAsynchronousRequest(
      (NSUrlRequest)request, //shouldn't this be inRequest? 
      NSOperationQueue.MainQueue, 
      delegate(NSUrlResponse inResponse, NSData inData, NSError inError) 
      { 
       bool error = ... //determine if we have an error 

       if(error) 
        tcs.SetException(new Exception(".. error message here ..")); //if we have an error, use the SetException method to set the exception for the Task 
       else 
       { 
        CustomHttpResponse result = ... // if we don't have an error, get result 
        tcs.SetResult(result); //set the result 
       } 
      }); 

    return tcs.Task; 
} 

请注意,该方法不再使用async关键字。