Created
November 3, 2010 13:13
-
-
Save shoover/661058 to your computer and use it in GitHub Desktop.
wraps an action in an asynchronous Post on the current synchronization context
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// usage: | |
// // In a UI event handler: | |
// BarAsync(result => label.Text = result); | |
// | |
// void BarAsync(Action<int> completed) { | |
// completed = completed.Marshal(); | |
// ThreadPool.QueueUserWorkItem(() => completed(42)); | |
// } | |
// | |
// Here's what it replaces. You'd need one of these for each delegate type | |
// you want to Marshal (Action, Action<T1,T2>, WaitCallback, etc). | |
// public static Action<T> Marshal<T>(this Action<T> self) | |
// { | |
// var sync = SynchronizationContext.Current; | |
// if (sync == null) | |
// { | |
// return self; | |
// } | |
// return t => sync.Post(state => self(t), null); | |
// } | |
public static class ActionExt | |
{ | |
/// <summary> | |
/// Returns a delegate that invokes action in a Post on the current syncronization context. | |
/// </summary> | |
public static T MarshalAction<T>(this T action) // the compiler doesn't allow "where T:Delegate" | |
{ | |
Debug.Assert(action is Delegate); | |
var invoke = action.GetType().GetMethod("Invoke"); | |
Debug.Assert(invoke.ReturnType == typeof(void)); | |
var sync = SynchronizationContext.Current; | |
if (sync == null) | |
{ | |
return action; | |
} | |
var args = invoke.GetParameters().Select(p => Expression.Parameter(p.ParameterType, p.Name)). | |
ToArray(); | |
var poster = Expression.Lambda<T>( | |
Expression.Call( | |
Expression.Constant(sync), | |
typeof(SynchronizationContext).GetMethod("Post"), | |
Expression.Lambda<SendOrPostCallback>( | |
Expression.Invoke(Expression.Constant(action), args), | |
Expression.Parameter(typeof(object), "ignore")), | |
Expression.Constant(null)), | |
args); | |
return poster.Compile(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment