Il modo migliore per convertire il metodo async basato su callback in attività attendibili

Quale sarebbe il modo migliore per convertire / avvolgere un metodo asincrono “classico” che utilizza un callback a qualcosa che restituisce un’attività (attendibile)?

Ad esempio, dato il seguente metodo:

public void GetStringFromUrl(string url, Action onCompleted); 

L’unico modo che conosco per avvolgere questo in un metodo che restituisce un compito è:

 public Task GetStringFromUrl(string url) { var t = new TaskCompletionSource(); GetStringFromUrl(url, s => t.TrySetResult(s)); return t.Task; } 

È questo l’unico modo per realizzare questo?

E c’è un modo per racchiudere la chiamata a GetStringFromUrl (url, callback) nell’attività stessa (ovvero la chiamata stessa verrebbe eseguita all’interno dell’attività anziché in modo sincrono)

Il tuo codice è breve, leggibile ed efficiente, quindi non capisco perché stai cercando alternative, ma non riesco a pensare a nulla. Penso che il tuo approccio sia ragionevole.

Non sono nemmeno sicuro del perché pensi che la parte sincrona sia ok nella versione originale, ma vuoi evitarla in quella basata su Task . Se pensi che la parte sincrona potrebbe richiedere troppo tempo, correggila per entrambe le versioni del metodo.

Ma se vuoi eseguirlo in modo asincrono (cioè sul ThreadPool ) solo nella versione Task , puoi usare Task.Run() :

 public Task GetStringFromUrl(string url) { return Task.Run(() => { var t = new TaskCompletionSource(); GetStringFromUrl(url, s => t.TrySetResult(s)); return t.Task; }); } 

L’implementazione presunta è perfettamente adatta a questo presupponendo che la funzione di callback gestisca solo situazioni di successo. Cosa succede attualmente se si verifica un’eccezione all’interno delle basi asincrone dell’implementazione GetStringFromUrl? Non c’è un modo reale per loro di propagarlo alla chiamata Action … lo inghiottono e restituiscono nulla o qualcosa?

L’unica cosa che consiglierei è quella di seguire la nuova convenzione di denominare i metodi asincroni con il suffisso XXXAsync.