我是C和多线程的新手,所以如果这是一个重复的问题,我很抱歉,但作为一个新手,我的问题似乎与我读过的其他问题略有不同。
我的gui运行在一个(主)线程中。它调用在单独线程中运行的后台任务(在dll中——我也在编写这个任务)。dll不了解gui(即它不能引用gui类)。
现在,假设我想根据dll线程的状态更新gui上的进度条->我正在做的是在dll中创建一个事件,每个x%将触发一个事件,gui将订阅该事件。当触发事件时,gui将更新进度条。
我的问题:
创建事件的方法是最好的方法吗(考虑到dll不能引用gui)?
如何确保上述方法是“事件安全的”?我是否应该传递事件的进度百分比以确保线程安全,或者是否有更多的进度百分比?
更新gui时是否需要使用invoke?我看到一篇文章建议我这么做,但我不明白为什么,因为更新栏是在gui线程中完成的??!
希望你能为我澄清这一点!
谢谢

最佳答案

1.-我一直用这种方法,是的,它会起作用的
2.-只要向事件处理程序传递一个int,变量就可以安全地读取。但是,当您从代码中激发事件时,请这样做

private void UpdatePercentage(int a)
{
    var myEvent = PercentageUpdatedEvent
    if(myEvent != null)
         myEvent(this, new ProgressBarEventArgs(a));
}

原因是,如果在空检查和调用之间取消了事件的描述,则不会出现异常。
3.-正如其他人提到的,您需要调用invoke,因为事件将在dll的线程上运行。但是,对于控件,在没有endenvoike的情况下调用begininvoke是合法的,因此调用在dll线程上是非阻塞的。
这是我经常使用的模式
private myClass_OnPercentageUpdatedEvent(object a, ProgressBarEventArgs e)
{
    if(progressBar.InvokeRequired)
        progressBar.BeginInvoke((Action<object,ProgressBarEventArgs>)myCless_OnPercentageUpdatedEvent, a, e);
    else
    {
        progressBar.Value = e.Value;
    }
}

08-25 11:03
查看更多