2015-12-09 3 views
2

Это вопрос C#, хотя код написан с использованием Xamarin iOS. Я хотел бы узнать, как я могу объединить метод Task с функцией async и делегатом callback. Поэтому в приведенном ниже примере кода я хотел бы вызвать функцию 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 ключевое слово.

Смежные вопросы