在一个线程中比较来自另一个线程的值C#
我想在我的应用程序中使用BackgroundWorker。我明白了,当我想这样做的时候:在一个线程中比较来自另一个线程的值C#,c#,multithreading,comparison-operators,C#,Multithreading,Comparison Operators,我想在我的应用程序中使用BackgroundWorker。我明白了,当我想这样做的时候: buttonStart.Enabled = false; 在主线程中,使用另一个线程,我应该这样做: if (buttonStart.InvokeRequired) { buttonStart.Invoke(new Action(() => buttonStart.Enabled = false)); } else buttonStart.Enabled = false; 但当涉及到比较操作时:
buttonStart.Enabled = false;
在主线程中,使用另一个线程,我应该这样做:
if (buttonStart.InvokeRequired) { buttonStart.Invoke(new Action(() => buttonStart.Enabled = false)); }
else buttonStart.Enabled = false;
但当涉及到比较操作时:
if(tabControlDbSwitch.SelectedIndex == 0)
它不起作用。
所以,我的问题是:
if ((!tabControlDbSwitch.InvokeRequired && tabControlDbSwitch.SelectedIndex == 0) ||
(tabControlDbSwitch.InvokeRequired && /*What should I write here?*/))
也许你们给了我一些提示,因为我在多线程方面完全是新手,但我想尽快学习
也就是说,我听说有时候使用BeginInvoke比调用更好,但我不知道为什么以及何时使用。CheckSelection是您从返回此if代码的函数中调用的函数
public void CheckSelection()
{
if (tabControlDbSwitch.InvokeRequired)
{
tabControlDbSwitch.Invoke(new Action(() => { CheckTabSelection(); }));
}
else
CheckTabSelection();
}
public void CheckTabSelection()
{
if (tabControlDbSwitch.SelectedIndex == 0)
{
// Do my work .....
}
}
你说你听说过有时候使用BeginInvoke比调用更好,但我不知道为什么和什么时候。invoke和begininvoke有两种类型:委托和控制。在您的示例中,您使用的是Contol.Invoke
- Invoke:在同一线程上同步执行
- Delegate.BeginInvoke:在线程池线程上异步执行意味着在begin invoke中调用的函数将在线程池中的新线程上执行,您可以继续在同一线程上执行操作(并行执行)
- Invoke:在UI线程上执行,但调用线程将在继续之前等待调用函数的完成
- Control.BeginInvoke:在UI线程上执行,调用线程不会等待调用的函数完成。 是的,我们建议使用Control.BeginInvoke而不是Control.Invoke,因为您不必担心死锁
if(tabControlDbSwitch.InvokeRequired)
并始终使用
tabControlDbSwitch.Invoke(new Action(() => { CheckTabSelection(); }));
在某些情况下,此函数是从UI主线程调用的,那么您的代码将挂起并导致死锁。CheckSelection是您从返回此代码的函数调用的函数
public void CheckSelection()
{
if (tabControlDbSwitch.InvokeRequired)
{
tabControlDbSwitch.Invoke(new Action(() => { CheckTabSelection(); }));
}
else
CheckTabSelection();
}
public void CheckTabSelection()
{
if (tabControlDbSwitch.SelectedIndex == 0)
{
// Do my work .....
}
}
你说你听说过有时候使用BeginInvoke比调用更好,但我不知道为什么和什么时候。invoke和begininvoke有两种类型:委托和控制。在您的示例中,您使用的是Contol.Invoke
- Invoke:在同一线程上同步执行
- Delegate.BeginInvoke:在线程池线程上异步执行意味着在begin invoke中调用的函数将在线程池中的新线程上执行,您可以继续在同一线程上执行操作(并行执行)
- Invoke:在UI线程上执行,但调用线程将在继续之前等待调用函数的完成
- Control.BeginInvoke:在UI线程上执行,调用线程不会等待调用的函数完成。 是的,我们建议使用Control.BeginInvoke而不是Control.Invoke,因为您不必担心死锁
if(tabControlDbSwitch.InvokeRequired)
并始终使用
tabControlDbSwitch.Invoke(new Action(() => { CheckTabSelection(); }));
在某些情况下,这个函数是从UI主线程调用的,那么您的代码将挂起并导致死锁。下面是另一种允许Invoke()返回值的方法 通过这种方式,您的代码流动得更好一些:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
if (GetSelectedIndex(this.tabControlDbSwitch) == 0)
{
Console.WriteLine("Success!");
}
}
private delegate int ReturnSelectedIndex(TabControl tb);
private int GetSelectedIndex(TabControl tb)
{
if (tb.InvokeRequired)
{
return (int)tb.Invoke(new ReturnSelectedIndex(GetSelectedIndex), new Object[] { tb });
}
else
{
return tb.SelectedIndex;
}
}
下面是另一种允许Invoke()返回值的方法 通过这种方式,您的代码流动得更好一些:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
if (GetSelectedIndex(this.tabControlDbSwitch) == 0)
{
Console.WriteLine("Success!");
}
}
private delegate int ReturnSelectedIndex(TabControl tb);
private int GetSelectedIndex(TabControl tb)
{
if (tb.InvokeRequired)
{
return (int)tb.Invoke(new ReturnSelectedIndex(GetSelectedIndex), new Object[] { tb });
}
else
{
return tb.SelectedIndex;
}
}