poziva ka web-api servisima pa se javlja potreba za "elegantnim"
i univerzalnim mehanizmom koji se tiče asinhronih operacija.
Za početak, mehanizam treba da omogući sledeće varijante:
1. Pokretanje nove operacije uz otkazivanje trenutno aktivne operacije
- ukoliko uopšte prethodna postoji, bez čekanja da se ona završi
2. Pokretanje nove operacije samo ako ne postoji trenutno aktivna
Pokušao sam da pronađem reentrancy rešenja online, međutim,
uglavnom se radi o varijantama koje mi ne trebaju ili se radi o
copy/paste rešenjima sa varijablama kakva sam već ranije koristio:
https://blogs.msdn.microsoft.c...-the-patterns-to-deal-with-it/
Pošto async/await može da bude prilično čupav za debugging,
pristalica sam gotovog kvalitetnog rešenja ali ga ne pronalazim :(
Ovo je moje rešenje ali nisam siguran što se tiče robustnosti:
Async operation coordinator:
public class AsyncOperation<T>
{
// Current state
private Task<T> task;
private CancellationTokenSource cts;
public Task<T> Run(Func<CancellationToken, Task<T>> action, bool cancelPrevious = true)
{
// Return current task if known and don't wish to cancel
if (!cancelPrevious && task?.IsCompleted == false) return task;
// Cancel current task
if (task != null)
{
cts.Cancel();
cts = null;
task = null;
}
// Run new task
cts = new CancellationTokenSource();
task = action(cts.Token);
return task;
}
}
Use case:
// Operation coordinator instance
private AsyncOperation<int> asyncFoo = new AsyncOperation<int>();
// Button click handler
private async void buttonFoo_Click(object sender, EventArgs e)
{
// Run/restart foo operation
await asyncFoo.Run(ct => Foo(ct, 10, 20));
}
// Actual custom operation
private async Task<int> Foo(CancellationToken ct, int a, int b)
{
try
{
// Call service here
await Task.Delay(5000, ct);
// Call service here
await Task.Delay(5000, ct);
}
catch (TaskCanceledException)
{
return 0;
}
// Check for cancellation
if (ct.IsCancellationRequested) return 0;
// Process results here
// ...
return 1;
}
Da li postoji neko gotovo rešenje?
Šta bi bile zamerke odnosno saveti za improvement?