In the current project, I have a simple component that can be removed from the visual studio toolbar in Forms and UserControls in the WinForms application.
It worked just fine as it is - and just wraps the SynchronizationContext submission and publishing methods captured during ISupportInitialize.BeginInit (UI context for form / control ownership).
Here is the existing code for the component in it the simplest form.
public class SyncContextComponent : Component, ISupportInitialize
{
private SynchronizationContext _context;
public SyncContextComponent() { }
public SyncContextComponent(IContainer container)
{
container.Add(this);
}
void ISupportInitialize.BeginInit()
{
_context = SynchronizationContext.Current;
}
void ISupportInitialize.EndInit() { }
public void Post(Action action)
{
_context.Post(new SendOrPostCallback(_ => action()), null);
}
public void Send(Action action)
{
_context.Send(new SendOrPostCallback(_ => action()), null);
}
}
I now needed to expand this to support return values, and was considering various ways ...
I am interested in understanding the implications of the following three ways to solve this problem, and if there is a “better” way.
: , , - , 1 arg1 TResult, .. Func<T1, TResult>. , , , Func<TResult> , , 9args Func<T1,T2....T9,TResult>, Action.
Send0: - , :
public TResult Send0<T1, TResult>(Func<T1, TResult> func, T1 arg1)
{
TResult retval = default(TResult);
_context.Send(new SendOrPostCallback((x) =>
{
retval = func(arg1);
})
, null);
return retval;
}
Send1: - stackoverflow, , , , , state arg. , - , , , :
private class SendFuncState1<T1, TResult>
{
public TResult Result { get; set; }
public T1 Arg1 { get; set; }
}
public TResult Send1<T1, TResult>(Func<T1, TResult> func, T1 arg1)
{
SendFuncState1<T1, TResult> state = new SendFuncState1<T1, TResult>()
{
Arg1 = arg1
};
_context.Send(new SendOrPostCallback((x) =>
{
var state0 = (SendFuncState1<T1, TResult>)x;
state0.Result = func(state0.Arg1);
})
, state);
return state.Result;
}
Send2: - , , , , Func? - :
private class SendFuncState2<T1, TResult>
{
public Func<T1, TResult> Func { get; set; }
public TResult Result { get; set; }
public T1 Arg1 { get; set; }
}
public TResult Send2<T1, TResult>(Func<T1, TResult> func,
T1 arg1)
{
SendFuncState2<T1, TResult> state = new SendFuncState2<T1, TResult>()
{
Func = func,
Arg1 = arg1
};
_context.Send(new SendOrPostCallback((x) =>
{
var state0 = (SendFuncState2<T1, TResult>)x;
state0.Result = state0.Func(state0.Arg1);
})
, state);
return state.Result;
}
, , WinForms, 10k ( )
.
, /.
So - is Send0 fine - / ?
- - ?