[ dusans @ 09.09.2017. 13:43 ] @
Počinjem rad na projektu (wpf client) koji će zahtevati gomilu 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: Code (csharp): 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: Code (csharp): // 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? |