Sì, è possibile. Il TAP è solo una ragionevole formalizzazione delle migliori pratiche quando si lavora con il codice asincrono. In pratica un metodo TAP
- Restituisce un 'caldo' (in esecuzione) o
Task
Task<TResult>
.
- ha un 'Async' suffisso (ad esempio
SomeMethodAsync(...)
).
- È sovraccarico per accettare un token di cancellazione.
- ritorna rapidamente al chiamante (con piccolo fase di inizializzazione).
- Non lega una discussione se I/O è vincolato.
Così, un esempio potrebbe essere
private Task SomeMethodAsync(CancellationToken token)
{
return Task.Factory.StartNew(() =>
{
// Do something...
}, token);
}
uso del metodo e collegare continuazione che utilizza il contesto di sincronizzazione UI.
private void SomeOtherMethod()
{
var tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;
TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext()
// Options 1.
Task t = SomeMethodAsync(token);
Task c = t.ContinueWith(ant =>
{
/* Do something and check exceptions */
}, CancellationToken.None,
TaskContinuationOptions.None,
scheduler);
// Options 2.
SomeMethodAsync(token).ContinueWith(ant =>
{
/* Do something and check exceptions */
}, CancellationToken.None,
TaskContinuationOptions.None,
scheduler);
}
o farlo tutto in una volta sola
Task t = Task.Factory.StartNew(() =>
{
/* Do Something */
}, token).ContinueWith(ant =>
{
/* Do something on UI thread after task has completed and check exceptions */
}, CancellationToken.None,
TaskContinuationOptions.None,
scheduler);
È anche possibile implementare manualmente il modello di TAP per un migliore controllo dell'attuazione. Per implementare personalmente il TAP, creare un oggetto TaskCompletionSource<TResult>
, eseguire l'operazione asincrona e al termine, chiamare il metodo SetResult
, SetException
o SetCanceled
o la versione Try
di uno di questi metodi. Quando si implementa manualmente un metodo TAP, è necessario completare l'attività risultante al termine dell'operazione asincrona rappresentata. Per esempio:
public static Task<int> ReadTask(this Stream stream,
byte[] buffer, int offset, int count, object state)
{
var tcs = new TaskCompletionSource<int>();
stream.BeginRead(buffer, offset, count, ar =>
{
try { tcs.SetResult(stream.EndRead(ar)); }
catch (Exception exc) { tcs.SetException(exc); }
}, state);
return tcs.Task;
}
Consumare il TaskCompleationSource
da parte del consumatore.
Spero che questo aiuti.
solo per essere sicuri di non perdere su nulla e non confondere i numeri di versione # .NET e C: se _potete_ compila il C# 5 codice che utilizza 'attendono/async' ad un NET 4.0 assembly. Devi solo fare riferimento al pacchetto di targeting asincrono (è su nuget) per farlo funzionare correttamente. Se per qualche motivo sei bloccato con il compilatore C# 4, allora vedi le risposte alla tua domanda, che è sì. – jods