2016-10-19 4 views
1

Es scheint wie direkt nach dem Aufruf meiner ersten asynchronen Methode (GetBar() in diesem Beispiel) die IsCancellationRequested der CancellationToken auf True festgelegt ist, aber ich will das nicht und verstehe nicht, warum es passiert.Warum wird dieses CancellationToken storniert?

Dies ist in einer Azure Cloud Service-Worker-Rolle, wenn dies von Bedeutung ist.

Ich habe CancellationTokens schon einmal in einem anderen Projekt erfolgreich verwendet und ich verwende ein ähnliches Setup hier. Der einzige Unterschied, den ich kenne, ist, dass es sich um einen Azure Cloud Service handelt. Irgendeine Idee, warum IsCancellationRequested auf wahr gesetzt wird?

+1

Welcher andere Code berührt 'cancellationTokenSource' neben den zwei Zeilen, die Sie in' Run() 'gezeigt haben, kann' Run() 'auch mehrfach aufgerufen werden? Wenn ich raten müsste, würde ich sagen, dass Sie eine Race Condition mit dem 'this.cancellationTokenSource.Token' innerhalb des Lambadas haben und dies bewirkt, dass der Token in' Foo.Bar '('um nicht das gleiche Token zu sein, das übergeben wurde) übergeben wird als der zweite Parameter von 'Task.Run (' –

+1

Erhalten Sie eine Ausnahme für 'GetBar' geworfen? Überprüfen Sie dies, und sehen Sie, ob es hilft: http://StackOverflow.com/questions/13489065/best-Practice- to-call-configurateawait-für-alle-server-side-code –

+1

Könnte 'OnStop' nach Ihrem Update aufgerufen worden sein, während Sie auf' FooService.GetBar() 'gewartet haben? Vielleicht fügen Sie eine Form der Protokollierung hinzu, um zu sehen wenn 'OnStop' vor dem' token.ThrowIfCancellationRequested(); 'aufgerufen wird und nach dem' var bar = await ... ' –

Antwort

1

Es erscheint OnStop wurde aufgerufen, während Sie auf FooService.GetBar() warten, um abzuschließen. Vielleicht fügen Sie eine Form der Protokollierung, um zu sehen, ob OnStop zwischen der token.ThrowIfCancellationRequested(); aufgerufen wird und nach der var bar = await ... zurück zu bestätigen.

Das ist der Grund, warum das Token abgebrochen wird.

Um das Problem zu lösen, müssen Sie sicherstellen, the overridden Run method does not return till the work is complete.

public override void Run() 
{ 
    this.cancellationTokenSource = new CancellationTokenSource(); 
    this.runTask = Task.Run(() => Foo.Bar(this.cancellationTokenSource.Token), this.cancellationTokenSource.Token); 
    this.runTask.Wait(); //You may need a try/catch around it 
} 
+0

Nur um zu verdeutlichen, der Grund 'OnStop' wird aufgerufen, weil meine 'Run' Methode endet. Gefunden diese Informationen hier: https://azure.microsoft.com/en-us/documentation/articles/cloud-services-role-lifecycle-dotnet/#run-method – MattM

+0

Macht Sinn. Meine Antwort wurde aktualisiert, um die Info zu enthalten. –

Verwandte Themen