2013-08-05 15 views
20

Mam następujący kod tutajPierwsze wartość zwracana z Task.Run

public static async Task<string> Start(IProgress<ProcessTaskAsyncExProgress> progress) 
    { 
     const int total = 10; 
     for (var i = 0; i <= total; i++) 
     { 
      await Task.Run(() => RunLongTask(i.ToString(CultureInfo.InvariantCulture))); 
      if (progress != null) 
      { 
       var args = new ProcessTaskAsyncExProgress 
       { 
        ProgressPercentage = (int)(i/(double)total * 100.0), 
        Text = "processing " + i 
       }; 
       progress.Report(args); 
      } 
     } 
     return "Done"; 
    } 

    private static string RunLongTask(string taskName) 
    { 
     Task.Delay(300); 
     return taskName + "Completed!"; 
    } 

W tej linii:

await Task.Run(() => RunLongTask(i.ToString(CultureInfo.InvariantCulture))); 

Jak mogę odzyskać wartość ciąg RunLongTask?

Próbowałem

var val = await Task.Run(() => RunLongTask(i.ToString(CultureInfo.InvariantCulture))).Result; 

ale pojawia się błąd "ciąg nie jest awaitable"

Odpowiedz

51

Zdjąć Result od końca. Gdy otrzymasz await, otrzymasz numer Result z powrotem od oczekiwanej metody.

var val = await Task.Run(() => RunLongTask(i.ToString(CultureInfo.InvariantCulture))); 
5

Nie jest to bezpośrednia odpowiedź na stare pytanie, ale dla innych, szukając:

„Normalnie” nie należy tego robić, ale czasami trzeba dopasować API biblioteki, dzięki czemu można użyj funkcji otoki jak poniżej:

private async Task<string> WrapSomeMethod(string someParam) 
{ 
    //adding .ConfigureAwait(false) may NOT be what you want but google it. 
    return await Task.Run(() => SomeObj.SomeMethodAsync(someParam)).ConfigureAwait(false); 
} 

a następnie zadzwonić, że zamiast z .Result jak poniżej:

string blah = WrapSomeMethod(someParam).Result;