Ich würde sagen, die folgenden zwei Code-Schnipsel, die ich habe, sind gleichwertig, aber sie sind nicht.Extension-Methode entspricht nicht direkt Anruf
Die folgende korrekt arbeitet:
var entry3 = Task.Run(async() => await entry2.GetMemberGroupsAsync(false)).WaitForResult().FirstOrDefault();
Der folgende Code, wo ich gerade bewegt die Task.Run.WaitForResult
Kette in einem Verlängerungsverfahren, nicht funktioniert, sondern erzeugt einen Deadlock:
var entry3 = entry2.GetMemberGroupsAsync(false).RunSynchronouslyAndReturnResult().FirstOrDefault();
public static T RunSynchronouslyAndReturnResult<T>(this Task<T> task)
{
return Task.Run(async() => await task).WaitForResult();
}
Warum sind diese beiden Codefragmente nicht gleichwertig?
Der Vollständigkeit halber wird die Methode GetMemberGroupsAsync
von Microsoft Azure Graph API zur Verfügung gestellt, und die Funktion WaitForResult ist unten definiert. Soweit ich sehen kann, macht es nichts anderes abhängig von dem Anrufernamen oder etw. dass, wie:
public static TResult WaitForResult<TResult>(this Task<TResult> task,
bool continueOnCapturedContext = false)
{
if (task == null)
{
throw new ArgumentNullException("task");
}
try
{
return PreventForDeadLocks(task, continueOnCapturedContext).Result;
}
catch (AggregateException ex)
{
if (ex.InnerExceptions.Count == 1)
{
throw ex.InnerExceptions[0];
}
throw;
}
}
public static async Task<TResult> PreventForDeadLocks<TResult>(this Task<TResult> task,
bool continueOnCapturedContext = false)
{
return await task.ConfigureAwait(continueOnCapturedContext: continueOnCapturedContext);
}
Noch schlimmer, 'PreventForDeadlocks' verhindert keine Deadlocks. ** Es gibt kein Sync-über-Async-Muster, das in allen Situationen funktioniert! ** –
Warum nicht einfach 'var entry3 = (warten Sie auf entry2.GetMemberGroupsAsync (false)). FirstOrDefault();'? Liegt es daran, dass Sie die Methode, die diesen Code enthält, in "async" machen müssen? In der Regel lässt man das 'async'-'await'-Muster bis zu den Ereignissen durchblubbern und macht dann diese' async'-'away' (fire and forget). – juharr
@juharr nur, dass ich keine Ereignisse habe - der Code ist in einem WebAPI-Endpunkt. Kann ich diesen WebAPI-Endpunkt asynchron machen? – Alexander