Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This will give you what you need without needing to do any ilgen, and way simpler. It works with any kind of event delegates; you just have to create a different handler for each number of parameters in your event delegate. Below are the handlers you'd need for 0..2, which should be the vast majority of your use cases. Extending to 3 and above is a simple copy and paste from the 2-parameter method. </p> <p>This is also more powerful than the ilgen method because you can use any values created by the event in your async pattern.</p> <pre><code>// Empty events (Action style) static Task TaskFromEvent(object target, string eventName) { var addMethod = target.GetType().GetEvent(eventName).GetAddMethod(); var delegateType = addMethod.GetParameters()[0].ParameterType; var tcs = new TaskCompletionSource&lt;object&gt;(); var resultSetter = (Action)(() =&gt; tcs.SetResult(null)); var d = Delegate.CreateDelegate(delegateType, resultSetter, "Invoke"); addMethod.Invoke(target, new object[] { d }); return tcs.Task; } // One-value events (Action&lt;T&gt; style) static Task&lt;T&gt; TaskFromEvent&lt;T&gt;(object target, string eventName) { var addMethod = target.GetType().GetEvent(eventName).GetAddMethod(); var delegateType = addMethod.GetParameters()[0].ParameterType; var tcs = new TaskCompletionSource&lt;T&gt;(); var resultSetter = (Action&lt;T&gt;)tcs.SetResult; var d = Delegate.CreateDelegate(delegateType, resultSetter, "Invoke"); addMethod.Invoke(target, new object[] { d }); return tcs.Task; } // Two-value events (Action&lt;T1, T2&gt; or EventHandler style) static Task&lt;Tuple&lt;T1, T2&gt;&gt; TaskFromEvent&lt;T1, T2&gt;(object target, string eventName) { var addMethod = target.GetType().GetEvent(eventName).GetAddMethod(); var delegateType = addMethod.GetParameters()[0].ParameterType; var tcs = new TaskCompletionSource&lt;Tuple&lt;T1, T2&gt;&gt;(); var resultSetter = (Action&lt;T1, T2&gt;)((t1, t2) =&gt; tcs.SetResult(Tuple.Create(t1, t2))); var d = Delegate.CreateDelegate(delegateType, resultSetter, "Invoke"); addMethod.Invoke(target, new object[] { d }); return tcs.Task; } </code></pre> <p>Use would be like this. As you can see, even though the event is defined in a custom delegate, it still works. And you can capture the evented values as a tuple.</p> <pre><code>static async void Run() { var result = await TaskFromEvent&lt;int, string&gt;(new MyClass(), "Fired"); Console.WriteLine(result); // (123, "abcd") } public class MyClass { public delegate void TwoThings(int x, string y); public MyClass() { new Thread(() =&gt; { Thread.Sleep(1000); Fired(123, "abcd"); }).Start(); } public event TwoThings Fired; } </code></pre> <p><a href="https://stackoverflow.com/a/12886260/171121">Here's a helper function</a> that'll allow you to write the TaskFromEvent functions in just one line each, if the above three methods are too much copy-and-paste for your preferences. Credit has to be given to max for simplifying what I had originally. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload