C#windows窗体-关于跨线程事件的问题
假设我创建了一个名为myClass的类,该类有一个名为myValue的属性,该属性具有任何类型,这无关紧要,比如:C#windows窗体-关于跨线程事件的问题,c#,multithreading,winforms,events,C#,Multithreading,Winforms,Events,假设我创建了一个名为myClass的类,该类有一个名为myValue的属性,该属性具有任何类型,这无关紧要,比如: class myClass { public delegate void OverTheLimitDlg(int arg); public event OverTheLimitDlg OverTheLimit; public myClass() { myValue = 0; } private int myvalue = 0;
class myClass
{
public delegate void OverTheLimitDlg(int arg);
public event OverTheLimitDlg OverTheLimit;
public myClass()
{
myValue = 0;
}
private int myvalue = 0;
public int myValue
{
get { return myvalue;}
set
{
myValue = value;
if(value > 5)
OvertheLimit(value);
}
}
}
我在表单上有一个名为myLabel的winforms标签,我在表单加载事件中创建一个对象类型的myClass,订阅其Overhelimit事件并启动backgroundworker:
myClass myObj;
private void Form_Load(object sender, EventArgs e)
{
myObj = new myClass();
myObj.OverTheLimit += SubsMethod;
backgroundworker.RunWorkerAsync();
}
private void backgroundworker_DoWork(...)
{
myObj.myValue = 10;
//Some expressions.
}
private void SubsMethod(int someInt)
{
myLabel.Text = "Oh it's over the limit!";
}
小结:我创建了一个类,从中实例化的对象可以触发事件。我让对象在一个线程中触发事件,它运行一个影响GUI对象的方法,一个在另一个线程中创建并运行的对象。我从来没有试过。在这种情况下会发生什么?它会导致错误吗?谢谢
在这种情况下会发生什么
myLabel.Text=“哦,超出了限制!”;
当此行试图从BackgroundWorker线程编辑myLabel
时,将抛出一个InvalidOperationException
。WinForms控件必须从创建它们的线程中更改,这就是存在WinForms控件的原因
您可以使用以下修改版本的SubsMethod()
,它将检查事件处理程序是否在另一个线程上运行,然后在必要时调用GUI线程上的标签更改
private方法(int-someInt)
{
if(myLabel.invokererequired){
Invoke(newmethodinvoker(()=>submethod(someInt));
返回;
}
myLabel.Text=“哦,这超出了限制!”;
}
当需要更新值时,可以使用BackgroundWorker的方法。因此,如果值超出了类定义的限制,则可以从处理程序引发事件。此事件在调用方的线程中引发。这里是UI线程。不要让不好的事情发生,不要被忽视Control.CheckForIllegalCrossThreadCalls=true
!谢谢你的回答。我会试试你的解决办法。我想知道的是,是否有一种方法可以在myValue属性的setter中调用它触发的事件。我的意思是我的对象不知道什么会订阅它的活动。它可能是一个winforms控件或其他一些不影响任何winforms控件的类静态方法。如果一开始就有办法调用它,我的对象肯定不会有问题。@Bee--有,但您需要将一些与UI相关的代码推送到myClass
对象中,这将非常糟糕。