Se non si desidera utilizzare async/await all'interno del vostro metodo, ma ancora "decorare" è in modo tale da essere in grado di utilizzare la parola chiave attendere dall'esterno, TaskCompletionSource.cs:
public static Task<T> RunAsync<T>(Func<T> function)
{
if (function == null) throw new ArgumentNullException(“function”);
var tcs = new TaskCompletionSource<T>();
ThreadPool.QueueUserWorkItem(_ =>
{
try
{
T result = function();
tcs.SetResult(result);
}
catch(Exception exc) { tcs.SetException(exc); }
});
return tcs.Task;
}
From here e here
Per supportare tale paradigma con Task, abbiamo bisogno di un modo per mantenere la facciata del Task e la possibilità di fare riferimento a un'operazione arbitraria asincrona come un'attività, ma di controllare la durata di tale attività in base alle regole dell'infrastruttura sottostante che fornisce l'asincronia e farlo in un modo che non costa in modo significativo. Questo è lo scopo di TaskCompletionSource.
I saw è anche utilizzato nella fonte .NET es. WebClient.cs:
[HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public Task<string> UploadStringTaskAsync(Uri address, string method, string data)
{
// Create the task to be returned
var tcs = new TaskCompletionSource<string>(address);
// Setup the callback event handler
UploadStringCompletedEventHandler handler = null;
handler = (sender, e) => HandleCompletion(tcs, e, (args) => args.Result, handler, (webClient, completion) => webClient.UploadStringCompleted -= completion);
this.UploadStringCompleted += handler;
// Start the async operation.
try { this.UploadStringAsync(address, method, data, tcs); }
catch
{
this.UploadStringCompleted -= handler;
throw;
}
// Return the task that represents the async operation
return tcs.Task;
}
Infine, ho trovato utili anche i seguenti:
ho chiesto questa domanda tutto il tempo. L'implicazione è che ci deve essere qualche thread da qualche parte che sta bloccando la chiamata I/O alla risorsa esterna. Quindi, il codice asincrono libera il thread di richiesta, ma solo a spese di un altro thread altrove nel sistema, giusto? No, per niente. Per capire perché le richieste asincrone si ridimensionano, traccerò un esempio (semplificato) di una chiamata I/O asincrona. Diciamo che una richiesta deve scrivere su un file. Il thread di richiesta chiama il metodo di scrittura asincrono. WriteAsync è implementato dalla Base Class Library (BCL) e utilizza le porte di completamento per l'I/O asincrono. Quindi, la chiamata WriteAsync viene passata al sistema operativo come una scrittura di file asincrona. Il sistema operativo comunica quindi con lo stack del driver, passando i dati per scrivere in un pacchetto di richiesta I/O (IRP).È qui che le cose si fanno interessanti: se un driver di periferica non può gestire immediatamente un IRP, deve gestirlo in modo asincrono. Quindi, il driver dice al disco di iniziare a scrivere e restituisce una risposta "in sospeso" al sistema operativo. Il sistema operativo passa la risposta "in sospeso" al BCL e il BCL restituisce un'attività incompleta al codice di gestione delle richieste. Il codice di gestione richieste attende l'attività, che restituisce un'attività incompleta da tale metodo e così via. Infine, il codice di gestione richieste termina con la restituzione di un'attività incompleta in ASP.NET e il thread di richiesta viene liberato per tornare al pool di thread.
Introduction to Async/Await on ASP.NET
Se l'obiettivo è quello di migliorare la scalabilità (piuttosto che di risposta), il tutto si basa sull'esistenza di un I/O esterno che offre l'opportunità di farlo.
Dal momento che non sappiamo cosa stai facendo, come dovremmo sapere qual è il modo migliore per farlo? Il modo in cui eseguirai un calcolo asincrono di un'immagine frattale è molto diverso rispetto al modo in cui eseguiresti un download asincrono di un file. –
Sto facendo una domanda generale su come strutturare un metodo. Voglio solo sapere da dove iniziare a trasformare i miei metodi già sincroni in quelli asincroni. –
OK, quindi cosa fa un tipico metodo sincrono * do *, e * perché vuoi renderlo asincrono *? –