2016-05-13 15 views
6

Ich habe ein Problem, wo eine Aufgabe abgeschlossen ist, aber nicht zurück. Ich habe eine Website und einen Webdienst auf verschiedenen Servern. Die Website ruft den Webservice an, der eine Bibliothek mit der Funktion myFunction() verwendet. Wenn ich myFunction über eine Konsolenanwendung auf dem Server des Web-Service anrufe, wird die Meldung wie erwartet zurückgegeben. Wenn ich den Aufruf von der Website zu dem Webdienst aufruft, um myFunction() aufzurufen, wird es zu "Schritt 3" aber nicht "Schritt 4" wechseln. Ich habe eine vereinfachte Version der Anrufe unten.warten Aufgabe nicht nach Abschluss

Ich bin neu zu async und erwarten, so würde jede Hilfe geschätzt werden.

+0

Wenn möglich, sollte 'myFunction()' auch async sein. Seltsame Dinge können passieren, wenn Sie bei einem asynchronen Anruf blockieren. Warum auch das 'Task.Run'-Geschäft in' bFunction'? –

+0

es gibt keinen Grund, warum 'Schritt 4' würde hier nicht ausgeführt werden – Jonesopolis

+0

@NateBarbettini Ich weiß nicht, warum die Task.Run Zeug. Ich habe versucht, den Code so weit wie möglich zu vereinfachen, aber du hast meine Aufmerksamkeit auf ein Stück gelenkt, das wichtig sein könnte. Ich verwende Code erneut, der für eine synchrone Aufgabe asynchron geschrieben wurde. Alles ohne das asynchrone Zeug umzuschreiben, wäre ein ziemliches Unterfangen. –

Antwort

5

Es ist fast sicher ein Deadlock in myFunction(). Schritt 4 wird für den Hauptthread ausgeführt, kann aber nicht ausgeführt werden, da der Hauptthread blockiert ist und auf GetResult() wartet.

private string myFunction() 
{ 
    string myStr = Task.Run(async() => await myDoWork()).Result; 

    return myStr; 
} 

private async Task<string> myDoWork() 
{ 
    logger.Debug("Step 1"); 
    string answer = await aFunction(); 

    logger.Debug("Step 4"); 

    return answer; 
} 

public async Task<string> aFunction() 
{ 
    logger.Debug("Step 2"); 
    return await bFunction(CancellationToken.None); 
} 

AsyncLock myLock = new AsyncLock(); 
public async Task<string> bFunction(CancellationToken cToken) 
{ 
    using (await myLock(cToken)) 
    { 
     logger.Debug("Step 3"); 
     result = "Hello"; 
     return result; 
    } 
} 

Im Allgemeinen Task.Run() should be called von der höchsten Ebene möglich:

Es sollte etwas näher an das sein. Halten Sie die Dinge so synchron wie möglich und lassen Sie den Anrufer entscheiden, ob er einen Hintergrund-Thread verwenden möchte.

+0

Vielen Dank! Das hat es behoben. –

+2

@JesseMcConahie die bessere Lösung ist, beheben Sie Ihren Code zu 'myFunction' async und nicht' Task.Run' noch '.GetResult()' –

+0

@ScottChamberlain Ich stimme zu. –

Verwandte Themen