Un modello riutilizzabile per convertire l’evento in attività

Mi piacerebbe avere un pezzo generico riutilizzabile di codice per avvolgere il modello EAP come attività , qualcosa di simile a ciò che Task.Factory.FromAsync fa per il modello APM BeginXXX/EndXXX .

Per esempio:

 private async void Form1_Load(object sender, EventArgs e) { await TaskExt.FromEvent( handler => this.webBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(handler), () => this.webBrowser.Navigate("about:blank"), handler => this.webBrowser.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(handler), CancellationToken.None); this.webBrowser.Document.InvokeScript("setTimeout", new[] { "document.body.style.backgroundColor = 'yellow'", "1" }); } 

Finora, assomiglia a questo:

 public static class TaskExt { public static async Task FromEvent( Action<EventHandler> registerEvent, Action action, Action<EventHandler> unregisterEvent, CancellationToken token) { var tcs = new TaskCompletionSource(); EventHandler handler = (sender, args) => tcs.TrySetResult(args); registerEvent(handler); try { using (token.Register(() => tcs.SetCanceled())) { action(); return await tcs.Task; } } finally { unregisterEvent(handler); } } } 

È ansible trovare qualcosa di simile, che tuttavia non richiede di digitare WebBrowserDocumentCompletedEventHandler due volte (per registerEvent / unregisterEvent ), senza ricorrere alla riflessione?