How to invoke Action<> modifying winforms control
I have the following function
private void UnsubscribeSubscribe(Action action)
{
action.BeginInvoke(action.EndInvoke, null);
}
Whenever I pass in an action that modifies my controls data source nothing happens. I know the action is being invoked because the query I'm running is returning results. I was reading that you can only modify winform controls from the same thread that added them. How can I make this work?
For example, running UnsubscribeSubscribe(() => { Foobar.DataSource = GetResults() });
GetResults()
will run properly 开发者_如何转开发but the data source will remain unchanged.
You need to invoke the delegate on the thread that created the control's underlying handle. Control.BeginInvoke is used for just that.
You are using the wrong method. A delegate's BeginInvoke() method always runs the delegate target on a threadpool thread. Poison to the user interface. You need to use Control.BeginInvoke(). Like the form's BeginInvoke method. While similarly named, it has nothing to do with a delegate's BeginInvoke() method. For one, you don't have to (and shouldn't) call EndInvoke().
if you need to make an action on a UI thread from the different thread then GUI thread then you should use Invoke
method like this (this example is for text box - from msdn):
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text;
}
}
There is also another approach using SynchronizationContext class - you can read about using it here
精彩评论