[英]Threading + TabControl in C#
这是一个有点奇怪的设置,我正在计划重做它,但是,如果没有别的,我希望我可以学习更多关于线程的结果。
目前,我有一个我正在构建的应用程序,它使用TabControl Windows窗体作为其设计的基础。 我有很多不同的事情需要做,所以我认为这可能是最好的方法。
现在,我正在将Macro函数编码到程序中,以便用户可以记录和回放鼠标和键盘操作。 这非常好,并将它与System.Timers.Timer混合也一直没问题。 但是,我正在使用的DLL使用Thread.Sleep(x)在击键和鼠标执行之间暂停线程。
此时,该按钮位于不同的标签页上,并切换到其他页面。 但是,空白点设置导致程序在等待宏执行完成时挂起。
为了更好地解释一下:
为了解决这个问题,我开始研究线程并了解如何使用它。 我在一个类中提出了以下代码:
Class X{
Thread othread;
...
public void Play()
{
if ((othread != null) && !(othread.IsAlive))
{
othread = new Thread(playValues);
GC.Collect();
}
else if (othread == null) othread = new Thread(playValues);
else return;
othread.Start();
}
public void PlayValues(){
...
Thread.CurrentThread.Abort();
}
}
线程被销毁的原因是,每次用户点击主窗体中的“播放”时,都会调用X.Play(),所以我需要重用线程(我研究过Monitor.Pulse(),但是给了我异步调用错误),或者每次完成时永久销毁它。
现在,目前,代码工作正常。 但是,每次我必须播放一个宏时,我一直在创建和销毁线程这一事实略显令人担忧,而且大量的GC调用也让我感到担忧。
我是否可以获得有关线程的一些指示,以及如何在没有此设置的情况下更好地完成此操作? 事实上,辅助选项卡是一个网页,宏在网页的表单上执行。
我还被告知'Thread.CurrentThread.Abort'是线程安全的,因此如果你想永久地结束它,这是结束线程的好方法,但如果我可以让线程重复其功能而不是杀死它,那就是精彩...
要重用播放线程,可以使用主线程中Set()
的AutoResetEvent
。 线程空闲时也是如此 - 主线程准备播放所需的数据,然后Set()
不同的AutoResetEvent
,导致播放线程启动。
因此,下面示例中的startPlayingAutoResetEvent
导致线程等待,直到主线程告诉它“go”,而stopPlayingAutoResetEvent
导致播放线程响应主线程,告诉它在没有执行步骤时“停止”。
主线程:
// prepare data to play
startPlayingAutoResetEvent.Set();
// ...
stopPlayingAutoResetEvent.Set();
玩线程:
while (true)
{
// wait for the main thread to signal "start"
startPlayingAutoResetEvent.WaitOne();
// ensure the stopPlaying is in an unsignalled state
stopPlayingAutoResetEvent.Reset();
// gather the data the main thread has prepared
while (stepsToPlay)
{
// wait until main thread signals to stop OR timeout has elapsed
if (stopPlayingAutoResetEvent.WaitOne(timeout))
{
// abort current run and put thread in idle mode, waiting for new commands
break;
}
else
{
// play next step
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.