在我的应用程序中,我要求通知用户有待处理的应用程序。
所以在mdiParent
我设置了一个BackgroundWorker
,它不断查询数据库以获取任何待处理的应用程序,如果它在MdiParent
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync(2000);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
fillnotification();
}
public void fillnotification()
{
int pending = 0;
if( Program.USERPK != 0)
{
DataTable dt = nftrans.getnotification();
pending = dt.Rows.Count;
String message = "You Have " + pending + " Applications Pending For Approval";
// toolTip1.SetToolTip(lblStatus , message);
toolTip1.Show(message , this, lblStatus.Location);
}
}
但是当我运行解决方案时,我得到一个例外:
跨线程操作无效:控制从其创建的线程以外的线程访问的“MainForm”。
我理解它是由于两个不同的线程但不能排除它。任何人都可以提出解决方案吗?我尝试了我在相关问题中阅读的想法,但找不到正确的解决方案
答案 0 :(得分:2)
无论何时从外部线程(后台工作者Executes an operation on a separate thread.)访问控件,您都需要进行某种调用。这将在拥有底层窗口句柄的线程上执行委托。
简单的事情;
this.Invoke(new MethodInvoker(delegate()
{
// toolTip1.SetToolTip(lblStatus , message);
toolTip1.Show(message, this, lblStatus.Location);
}));
可能适用于您的情况,只要您以前的代码没有访问控件,我不确定getnotification()
正在做什么。
答案 1 :(得分:1)
您正在更改工作线程上的UI(工具提示)。
这是不允许的。使用UI线程通过调用Window上的Invoke并将委托传递给更改工具提示的函数来更改工具提示。
答案 2 :(得分:1)
由于看起来工具提示的更改发生在工作线程的确切末尾,您可以使用RunWorkerCompleted
事件 - 您可以从那里修改UI线程,这就是此事件的设计目的。
当然,Chris Bucklers Invoke
解决方案也可行。
答案 3 :(得分:0)
更改fillnotification()以返回您的待处理值,并将其传递给DoWork()处理程序中的“e.Result”。现在连接RunWorkerCompleted()事件并检索后台操作的结果:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
e.Result = fillnotification();
}
public int fillnotification()
{
if (Program.USERPK != 0)
{
DataTable dt = nftrans.getnotification();
return dt.Rows.Count;
}
return -1;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
int pending = (int)e.Result;
if (pending != -1)
{
String message = "You Have " + pending.ToString() + " Applications Pending For Approval";
toolTip1.Show(message, this, lblStatus.Location);
}
}