Hto*_*onS 4 c# user-interface multithreading visual-studio-2010
我正在使用Visual Studio .NET 2010中的Windows窗体创建GUI应用程序C#.我有多个线程,例如:
Control.Invoke().我的目标:当用户在主窗体上按(x)时,我想确保正确关闭窗体.这意味着我希望我的连接关闭,所有侧线程终止等.我正在尝试使用FormClosing事件.在那里我将KillThreads标志设置为true并等待侧线程终止.每个都有一张支票,比如if(KillThreads)
return;
Run Code Online (Sandbox Code Playgroud)
但是有一个问题.如果我试图等待所有线程终止
for(;;)
if(ActiveSideThreads == 0)
break;
closeConnection();
Run Code Online (Sandbox Code Playgroud)
线程N3冻结被阻塞Invoke(); 当然是,因为主gui线程处于无限循环中.所以表格结束会永远延迟.
如果我将on-close操作实现为线程过程4,并在FromClosing事件处理程序中创建一个新线程,则表单在线程4终止之前立即关闭,并Invoke()抛出错误-t.4无法及时关闭线程3.如果我Join(), Invoke()再次阻止添加呼叫,并且线程3永远不会终止,那么线程4将永远等待.
我该怎么办?有什么方法可以解决这个问题吗?
首先决定你是否真的需要使用它Invoke.它现在已经有一段时间了,我认为这Invoke是在工作线程启动后在UI线程上发生操作的最过度使用的技术之一.另一种方法是在工作线程中创建某种类型的消息对象,描述需要在UI线程上执行的操作并将其放入共享队列.然后,UI线程将在某个时间间隔内轮询此队列System.Windows.Forms.Timer,并使每个操作发生.这有几个优点.
Invoke强加的UI和工作线程之间的紧密耦合.当然,Invoke非常有用,并且有很多理由继续使用这种方法.如果您决定继续使用,Invoke请阅读更多内容.
一个想法是KillThreads在Form.Closing事件中设置标志,然后通过设置取消关闭表单FormClosingEventArgs.Cancel = true.您可能希望让用户知道已请求关闭并且正在进行中.您可能希望禁用表单上的某些控件,以便无法启动新操作.所以基本上我们发信号通知已经请求了关闭,但是推迟关闭表单直到工作线程先关闭.要做到这一点,你可能想要启动一个定时器,定期检查工作线程是否已经结束,如果有,你可以调用Form.Close.
public class YourForm : Form
{
private Thread WorkerThread;
private volatile bool KillThreads = false;
private void YourForm_Closing(object sender, FormClosingEventArgs args)
{
// Do a fast check to see if the worker thread is still running.
if (!WorkerThread.Join(0))
{
args.Cancel = true; // Cancel the shutdown of the form.
KillThreads = true; // Signal worker thread that it should gracefully shutdown.
var timer = new System.Timers.Timer();
timer.AutoReset = false;
timer.SynchronizingObject = this;
timer.Interval = 1000;
timer.Elapsed =
(sender, args) =>
{
// Do a fast check to see if the worker thread is still running.
if (WorkerThread.Join(0))
{
// Reissue the form closing event.
Close();
}
else
{
// Keep restarting the timer until the worker thread ends.
timer.Start();
}
};
timer.Start();
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码调用Join,但它指定超时为0,这会导致Join调用立即返回.这应该保持UI抽取消息.
| 归档时间: |
|
| 查看次数: |
7486 次 |
| 最近记录: |