c#无法访问-a-disposed-object-工作线程访问的表单
我是一个比较新的c#用户,所以如果我犯了一些新手错误,请原谅我。我已搜索此错误的解决方法,但找不到适合我的实现 我有一个工作线程,它基本上是循环的,而booleanc#无法访问-a-disposed-object-工作线程访问的表单,c#,multithreading,C#,Multithreading,我是一个比较新的c#用户,所以如果我犯了一些新手错误,请原谅我。我已搜索此错误的解决方法,但找不到适合我的实现 我有一个工作线程,它基本上是循环的,而booleanisCalibrationActive是真的。在工作线程期间,我设置了一个回调来访问主线程中的标签,并根据工作线程更改文本。在主线程中的formclosing事件上,我将isCalibrationActive设置为false,从理论上讲,这将停止工作线程中的循环。一旦我关闭表单,就会出现错误 表单关闭事件代码: private voi
isCalibrationActive
是真的。在工作线程期间,我设置了一个回调来访问主线程中的标签,并根据工作线程更改文本。在主线程中的formclosing事件上,我将isCalibrationActive
设置为false,从理论上讲,这将停止工作线程中的循环。一旦我关闭表单,就会出现错误
表单关闭事件代码:
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
DialogResult result = MessageBox.Show("The Calibration stage is not yet complete. Are you sure you want to exit?", "Dialog Title", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
isCalibrationActive = false;
Thread.Sleep(10000);
return;
}
else
{
e.Cancel = true;
}
}
else
{
e.Cancel = true;
}
}
工作线程:编辑:很抱歉,我之前把测试代码留在了那里。
private void refreshXY()
{
var currentpath = new StringBuilder(255);
//store current directory and set to dll directory.
UnsafeNativeMethods.GetDllDirectory(currentpath.Length, currentpath);
UnsafeNativeMethods.SetDllDirectory( "D:\\UI_still_in_progress\\Debug" );
UnsafeNativeMethods.LoadLibrary("dllTESTER.dll");
while (isCalibrationActive)
{
xx = UnsafeNativeMethods.grabx();
yy = UnsafeNativeMethods.graby();
if (xx == 0) { xx = 0.001;}
if (yy == 0) { yy = 0.001;}
SetXlab(xx.ToString());
SetYlab(yy.ToString());
}
//restore old directory
UnsafeNativeMethods.SetDllDirectory(currentpath.ToString());
}
错误发生在基本相同的SetXlab
或SetYlab
功能期间。另外,我将它放在另一个线程中的原因是,它正在从另一个应用程序读取实时数据,需要不断更新。如下所示:
private void SetYlab(string yval)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.yshow.InvokeRequired)
{
SetTextCallback yD = new SetTextCallback(SetYlab);
if (isCalibrationActive) { this.Invoke(yD, new object[] { yval }); }
}
else
{
this.yshow.Text = yval;
}
}
具体来说,行
this.Invoke(yD,newobject[]{yval});}代码>是导致错误的原因。有什么办法可以避免这种情况吗?我可能会使用一个名为calGuiUpdateTimer
的System.Windows.Forms(SWF)计时器,带有Tick
类似的功能
xx = 0;
yy = 100;
xx = UnsafeNativeMethods.grabx();
yy = UnsafeNativeMethods.graby();
if (xx == 0) { xx = 0.001;}
if (yy == 0) { yy = 0.001;}
this.xshow.Text = xx.ToString();
this.yshow.Text = yy.ToString();
然后去掉isCalibrationActive
,改为calGuiUpdateTimer.Enabled
SWF定时器总是在GUI线程上运行,这样您就不必担心切换线程;您可以完全摆脱所有那些调用所需的垃圾函数。让你的东西更容易
也就是说,如果grabx
或graby
是可能运行缓慢的函数,那么此选项将使您的GUI结巴,并且SWF计时器是不可接受的。在这种情况下,请继续使用后台线程解决方案,并参阅以获得指导(同时请参阅以简化回调)。我可能会使用名为calGuiUpdateTimer
的System.Windows.Forms(SWF)计时器,并使用类似的Tick
函数
xx = 0;
yy = 100;
xx = UnsafeNativeMethods.grabx();
yy = UnsafeNativeMethods.graby();
if (xx == 0) { xx = 0.001;}
if (yy == 0) { yy = 0.001;}
this.xshow.Text = xx.ToString();
this.yshow.Text = yy.ToString();
然后去掉isCalibrationActive
,改为calGuiUpdateTimer.Enabled
SWF定时器总是在GUI线程上运行,这样您就不必担心切换线程;您可以完全摆脱所有那些调用所需的垃圾函数。让你的东西更容易
也就是说,如果grabx
或graby
是可能运行缓慢的函数,那么此选项将使您的GUI结巴,并且SWF计时器是不可接受的。在这种情况下,请继续使用后台线程解决方案,并参阅以获取指导(同时请参阅以简化回调)。grabx
和graby
运行方法是否合理快速?比如通常小于5毫秒,很少超过50毫秒,而且从不超过一秒钟?(新手犯的错误--C#“事实上”的编码标准使用PascalCase作为方法和属性,仅供参考;随意做你想做的事)是grabx
和graby
运行速度相当快的方法吗?比如一般少于5毫秒,很少超过50毫秒,而且从不超过一秒钟?(新手犯的错误--C#“事实上”的编码标准使用PascalCase作为方法和属性,仅供参考;随意做你想做的事)谢谢,我意识到我可以让worker线程更新全局变量,还有timer.tick事件更新表单:)谢谢,我意识到我可以让工作线程更新全局变量,而timer.tick事件更新表单:)