Ich habe Code, der ein Stornierungs-Token erstellt
public partial class CardsTabViewModel : BaseViewModel
{
public CancellationTokenSource cts;
public async Task OnAppearing()
{
cts = new CancellationTokenSource(); // << runs as part of OnAppearing()
Code, der es verwendet:
await GetCards(cts.Token);
public async Task GetCards(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
App.viewablePhrases = App.DB.GetViewablePhrases(Settings.Mode, Settings.Pts);
await CheckAvailability();
}
}
und Code, der dieses Stornierungs-Token später abbricht, wenn sich der Benutzer von dem Bildschirm entfernt, auf dem der obige Code ausgeführt wird:
public void OnDisappearing()
{
cts.Cancel();
Ist dies in Bezug auf das Abbrechen die richtige Methode, um das Token abzubrechen, wenn es in einer Aufgabe verwendet wird?
Insbesondere habe ich diese Frage geprüft:
Verwendung der IsCancellationRequested-Eigenschaft?
und es lässt mich denken, dass ich den Abbruch nicht richtig oder vielleicht auf eine Weise mache, die eine Ausnahme verursachen kann.
Sollte ich in diesem Fall nach dem Abbruch eine cts.Dispose () ausführen?
c#
xamarin
xamarin.forms
Alan2
quelle
quelle
Antworten:
CancellationTokenSource.Cancel()
ist ein gültiger Weg, um die Stornierung zu starten.Polling
ct.IsCancellationRequested
vermeidet das WerfenOperationCanceledException
. Aufgrund der Abfrage muss die Schleife wiederholt werden, bevor sie auf die Stornierungsanforderung reagiert.Wenn
GetViewablePhrases()
undCheckAvailability()
geändert werden kann, um a zu akzeptierenCancellationToken
, kann dies dazu führen, dass die Stornierung schneller erfolgt, und zwar auf Kosten vonOperationCanceledException
Werfens."sollte ich ein cts.Dispose () machen?" ist nicht so einfach ...
Ist eher eine Richtlinie als eine Regel.
Task
selbst ist wegwerfbar, aber kaum jemals direkt im Code angeordnet.Es gibt Fälle (wenn
WaitHandle
Rückruf-Handler verwendet werden oder die abgebrochen werden), in denen durch das Entsorgencts
eine Ressource freigegeben / ein GC-Stamm entfernt wird, der sonst nur von einem Finalizer freigegeben würde. Diese gelten nicht für Ihren aktuellen Code, können aber in Zukunft gelten.Anruf hinzufügen zu
Dispose
nach dem Abbrechen würde sicherstellen, dass diese Ressourcen in zukünftigen Versionen des Codes sofort freigegeben werden.Sie müssen jedoch entweder warten, bis der verwendete Code
cts
beendet ist, bevor Sie dispose aufrufen, oder den Code ändern, der nach der EntsorgungObjectDisposedException
von der Verwendung voncts
(oder seinem Token) verarbeitet werden soll.quelle
CancellationToken
Parameter zu akzeptieren ), könnten Sie das entsorgen,WaitHandle
während ein anderer Thread aktiv darauf wartet :(Dispose
ausOnDisappearing
.Cancel
...Cancel
der interne Timer (falls verwendet).Im Allgemeinen sehe ich eine faire Verwendung von Cancel Token in Ihrem Code, aber gemäß dem Task Async Pattern kann Ihr Code möglicherweise nicht sofort abgebrochen werden.
Um sofort zu antworten, sollte auch der Sperrcode aufgehoben werden
Es liegt an Ihnen, ob Sie entsorgen müssen. Wenn im unterbrochenen Code viele Speicherressourcen reserviert sind, sollten Sie dies tun.
quelle
Ich würde Ihnen empfehlen, einen Blick auf eine der .net-Klassen zu werfen, um zu verstehen, wie man mit Wartemethoden mit CanncelationToken umgeht. Ich habe SeamaphoreSlim.cs ausgewählt
Sie können die gesamte Klasse auch hier anzeigen: https://referencesource.microsoft.com/#mscorlib/system/threading/SemaphoreSlim.cs,6095d9030263f169
quelle