2016-06-15 7 views
1

Ich habe this documentation gelesen, die besagt, dass mit HostingEnvironment.QueueBackgroundWorkItem Aktion ausgeführt wird:Verzögert HostingEnvironment.QueueBackgroundWorkItem das Recycling wirklich?

in diesem ASP.NET von einem normalen Thread Workitem Unterscheidet sich verfolgen, wie viele Arbeitseinheiten registriert durch diese API sind derzeit am Laufen halten können und Die ASP.NET-Laufzeit versucht, das Herunterfahren von AppDomain zu verzögern, bis die Ausführung dieser Arbeitsaufgaben abgeschlossen ist. Diese API kann nicht außerhalb einer ASP.NET-verwalteten AppDomain aufgerufen werden. Das bereitgestellte CancellationToken wird beim Herunterfahren der Anwendung signalisiert. i gezwungen, ein Recycling durch den IIS-Manager

private void Check() { 
    HostingEnvironment.QueueBackgroundWorkItem(ct => CheckRecyclingBehaviour(ct));} 
} 

private async void CheckRecyclingBehaviour(CancellationToken ct) { 
    while (true) { 
    await Task.Delay(1000); 
    if (ct.IsCancellationRequested) { 
     AppendToFile("Recycling soon..."); 
     await Task.Delay(1000); 
     AppendToFile("But we still have time to finish..."); 
     break; 
    } 
    } 
} 

I check() (IIS 7) und nach einer gewissen Zeit ausgeführt haben:

Also habe ich diesen Beispielcode geschrieben.

Schließlich habe ich die debug.txt-Datei überprüft und es enthielt eine einzige Zeile: "Recycling bald ...".

Also ich denke, die CancellationToken wurde signalisiert, aber die AppDomain Shutdown wurde nicht wirklich verzögert (da der zweite Druck nie passiert ist).

Es scheint ziemlich seltsam, vor allem in Anbetracht mehrerer Beiträge, die ich gelesen habe, die sagen, dass die recycling will be delayed by 30 seconds.

Fehle ich etwas?

Antwort

3

Sie verwenden async void, und das ist, was Sie vermasselt. Wie ich in my MSDN article on async best practices, you should avoid async void beschreibe.

Ändern Sie async void in die richtige async Task, und Sie werden wahrscheinlich sehen, wie es richtig funktioniert.

Weitere Informationen: Es ist nicht trivial, den Abschluss einer async void Methode zu erkennen, so dass der Code, den Sie auf QueueBackgroundWorkItem gebucht haben, fast sofort (an der ersten await) abgeschlossen. Wenn ASP.NET heruntergefahren wird, legt es das Löschungs-Token fest (synchron schreibt die erste Zeile in die Datei) und wartet dann auf alle in der Warteschlange befindlichen Aufgaben. Da die Arbeit bereits abgeschlossen war, bricht sie sofort die App-Domäne ab und gibt den Rest der Methode auf. Wenn Sie eine async Task-Methode verwenden, wird QueueBackgroundWorkItem verstehen, dass der Code erst abgeschlossen wird, wenn die Aufgabe abgeschlossen ist.

+1

Eigentlich weiß ich nicht, ob das es vollständig beheben wird, kann ich falsch liegen, aber ich denke, die Kraft recyceln nicht Aufgaben im 'QueueBackgroundWorkItem' respektieren, nur wenn es" natürlich passiert "respektiert es die Warteschlange . Wenn man es in eine "Task" umwandelt, wird es für einen normalen Recyclingvorgang repariert, aber ich denke immer noch, dass ein erzwungener Recyclingvorgang sich genauso verhält. –

+0

Danke, ich wechselte zu 'Task' und es funktionierte. Scott, danke für die Warnung, aber glücklicherweise respektiert die Zwangsrecycling die laufende Aufgabe. – oavraham