gpt4 book ai didi

c# - C# 中的线程 + TabControl

转载 作者:行者123 更新时间:2023-11-30 12:49:51 27 4
gpt4 key购买 nike

这是一个有点奇怪的设置,我打算重做它,但是,如果不出意外,我希望我能因此学到更多关于线程的知识。

目前,我正在构建一个应用程序,它使用 TabControl Windows 窗体作为其设计的基础。我有很多不同的事情要做,所以我认为这可能是最好的方法。

现在,我在程序中编写了一个宏函数,以便用户可以录制和回放鼠标和键盘操作。这非常好,将它与 System.Timers.Timer 混合也没有问题。但是,我使用的 DLL 使用 Thread.Sleep(x) 在击键和鼠标执行之间暂停线程。

此时按钮在不同的tabpage,切换到不同的页面。但是,空白设置导致程序在等待宏执行完成时挂起。

为了更好地解释:

  • 用户点击主选项卡控件中的按钮。
  • Tabcontrol.SelectedIndex 切换到正确的页面,但不刷新页面(我尝试调用 this.Refresh(),它没有用)
  • 宏执行
  • Tabcontrol 完成了页面加载,但此时,必要的宏已经执行,加载的页面是多余的。

为了解决这个问题,我开始研究线程并了解如何使用它。我在一个类中想出了以下代码:

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 调用数量也让我担心。

我能得到一些关于线程的指示吗?如果没有这个设置,我如何才能做得更好?事实上,副标签是一个网页,宏是在网页的窗体上执行的。

  • 编辑:我不知道我是否没有说清楚,但宏使用的是鼠标和键盘模拟器。另一个选项卡是一个网络浏览器设置,它在里面嵌套了一个小程序,因此我正在模拟硬件功能以执行自动设置。这有帮助,因为我不需要锁定任何东西(所有鼠标和键盘调用都由模拟器操作,并且与第三选项卡控制的值无关),我只需要能够 a) 让线程执行每当用户按下按钮时,功能都相同,并且 b) 移除一些多余的 Material 。

我还被告知“Thread.CurrentThread.Abort”是线程安全的,因此如果您想永远结束它,这是结束线程的好方法,但如果我能让线程重复其功能而不是杀死它,那会很棒...

最佳答案

要重用播放线程,您可以使用您在主线程中Set()AutoResetEvent。当线程空闲时也是如此 - 主线程准备播放所需的数据,然后 Set() 一个不同的 AutoResetEvent,导致播放线程启动。

因此下面示例中的 startPlayingAutoResetEvent 导致线程等待,直到主线程告诉它“开始”,而 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
}
}
}

关于c# - C# 中的线程 + TabControl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10513471/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com