2015-12-09 42 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關鍵字。