Tengo un código que crea un token de cancelación
public partial class CardsTabViewModel : BaseViewModel
{
public CancellationTokenSource cts;
public async Task OnAppearing()
{
cts = new CancellationTokenSource(); // << runs as part of OnAppearing()
Código que lo usa:
await GetCards(cts.Token);
public async Task GetCards(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
App.viewablePhrases = App.DB.GetViewablePhrases(Settings.Mode, Settings.Pts);
await CheckAvailability();
}
}
y el código que luego cancela este token de cancelación si el usuario se aleja de la pantalla donde se está ejecutando el código anterior:
public void OnDisappearing()
{
cts.Cancel();
Con respecto a la cancelación, ¿es esta la forma correcta de cancelar el token cuando se usa en una Tarea?
En particular revisé esta pregunta:
Uso de la propiedad IsCancellationRequested?
y me hace pensar que no estoy haciendo la cancelación de la manera correcta o tal vez de una manera que pueda causar una excepción.
Además, en este caso, después de haber cancelado, ¿debería hacer un cts.Dispose ()?
c#
xamarin
xamarin.forms
Alan2
fuente
fuente
Respuestas:
CancellationTokenSource.Cancel()
es una forma válida de comenzar la cancelación.El sondeo
ct.IsCancellationRequested
evita el lanzamientoOperationCanceledException
. Debido a su sondeo, requiere una iteración del ciclo para completarse antes de que responda a la solicitud de cancelación.Si
GetViewablePhrases()
yCheckAvailability()
puede modificarse para aceptar aCancellationToken
, esto puede hacer que la cancelación sea más rápida para responder, a costa de haberlaOperationCanceledException
arrojado."¿debería estar haciendo un cts.Dispose ()?" no es tan sencillo ...
Es más una guía que una regla.
Task
en sí mismo es desechable, pero casi nunca está directamente dispuesto en código.Hay casos (cuando
WaitHandle
se utilizan controladores de devolución de llamada o cancelación) en los que la eliminacióncts
liberaría un recurso / eliminaría una raíz de GC que de otro modo solo sería liberada por un Finalizador. Estos no se aplican a su código tal como está, pero pueden hacerlo en el futuro.Agregar una llamada a
Dispose
después de cancelar garantizaría que estos recursos se liberen rápidamente en futuras versiones del código.Sin embargo, tendría que esperar a que
cts
termine el código que usa antes de llamar a disposed, o modificar el código para tratar elObjectDisposedException
uso dects
(o su token) después de la eliminación.fuente
CancellationToken
parámetro), podría estar desechandoWaitHandle
mientras otro hilo lo está esperando activamente :(Dispose
desdeOnDisappearing
.Cancel
...Cancel
hace es el temporizador interno (si se usa).En general, veo un uso justo de Cancelar token en su código, pero de acuerdo con el Patrón de sincronización de tareas, su código podría no cancelarse de inmediato.
Para responder de inmediato, el código de bloqueo también debe cancelarse
Depende de usted si debe Eliminar, si hay muchos recursos de memoria reservados en el código interrumpido, debe hacerlo.
fuente
Le recomendaría que eche un vistazo a una de las clases .net para comprender completamente cómo manejar los métodos de espera con CanncelationToken, recogí SeamaphoreSlim.cs
También puede ver toda la clase aquí, https://referencesource.microsoft.com/#mscorlib/system/threading/SemaphoreSlim.cs,6095d9030263f169
fuente