-1

在我的应用程序中,我需要通知用户有关待处理的应用程序。

所以在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”从创建它的线程以外的线程访问。

我理解这是由于两个不同的线程,但无法解决这个问题。任何人都可以提出解决方案吗?我尝试了我在相关问题中阅读的想法但找不到正确的解决方案

4

4 回答 4

2

每当您从外部线程(后台工作人员在单独的线程上执行操作。)访问控件时,您都需要进行某种调用。这会在拥有底层窗口句柄的线程上执行委托。

像这样简单的东西;

        this.Invoke(new MethodInvoker(delegate()
        {
        //   toolTip1.SetToolTip(lblStatus , message);
        toolTip1.Show(message, this, lblStatus.Location);

        }));

可能适用于您的情况,只要您以前的代码不访问控件,我不确定getnotification()在做什么。

于 2013-05-11T06:18:40.547 回答
1

您正在更改工作线程上的 UI(工具提示)。

这是不允许的。使用 UI 线程通过在 Window 上调用 Invoke 并将委托传递给更改工具提示的函数来更改工具提示。

于 2013-05-11T06:05:38.423 回答
1

由于似乎工具提示的更改发生在您的工作线程的确切末尾,您可以使用该RunWorkerCompleted事件 - 您可以从那里修改 UI 线程,这就是该事件的设计目的。

当然 Chris Bucklers 的Invoke解决方案也可以。

于 2013-05-11T06:29:36.310 回答
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);
        }
    }
于 2013-05-11T09:07:07.087 回答