如何解决C# WPF 线程:如何在事件函数中停止新创建的线程单击按钮不影响主线程
在下面的代码中,我想停止在 StartInvokeExplorer
函数中创建的线程。 StartInvokeExplorer
中的 starter 函数也是一个 keyhook 函数。
public void InvokeExplorerStart_Click(object sender,RoutedEventArgs e)
{
Automate.IsInvokeExplorerClicked = true;
if (InvokeExplorer.Content.Equals("InvokeExplorerStart"))
{
InvokeExplorer.Content = "InvokeExplorerStop";
StartInvokeExplorer();
//InvokeExplorer.dispatcher.BeginInvoke(new InvokeExplorerDelegate(StartInvokeExplorer));
}
else
{
InvokeExplorer.Content = "InvokeExplorerStart";
StopInvokeExplorer();
}
}
public void StartInvokeExplorer()
{
if (XmlDataGrid.SelectedCells.Count > 0)
{
StartupCount = 1;
thread = new Thread(() =>
{
Starter(StartupCount);
});
thread.IsBackground = true;
thread.Start();
}
else
{
MessageBox.Show("Please select the recorded row to fetch the new data ");
InvokeExplorer.Content = "InvokeExplorerStart";
}
}
private void Starter(int cnt)
{
try
{
if (cnt > 0)
{
Hook.GlobalEvents().MouseClick += (sender,e) =>
{
if (e.Button == MouseButtons.Left)
{
Automate.Show(e);
}
};
Hook.GlobalEvents().MouseDoubleClick += (sender,e) =>
{
Automate.IsDoubleClick = true;
Automate.Show(e);
Automate.IsDoubleClick = false;
};
System.Windows.Forms.Application.Run(new ApplicationContext());
}
else
{
Hook.GlobalEvents().dispose();
}
}
catch (Exception ex)
{
ErrorLog.Log(ex);
}
}
解决方法
据我所知,您想停止正在运行的线程。 就是这样。
首先,您需要创建一些停止逻辑。在您的情况下,它将是一些变量,例如:
bool threadShouldRun;
然后在你的线程函数中,你应该创建一个循环:
void MyThreadFunc()
{
while(threadShouldRun)
{
threadWork();
Thread.Sleep(100);
}
}
当您想停止线程时,只需将 threadShouldRun
变量设置为 false。
这里需要睡眠。如果没有这个,线程可能会使用 100% 的处理器内核。
,您可以将 AutoResetEvent
与 CancellationToken
结合使用。沿线的东西(代码未测试)
CancellationTokenSource cts;
AutoResetEvent autoResetEvent;
Thread thread;
public void ThreadStart()
{
cts = new CancellationTokenSource();
autoResetEvent = new AutoResetEvent();
thread = new Thread(new ParameterizedThreadStart(ThreadJob));
thread.Start(cts.Token);
}
public void ThreadStop()
{
cts?.Cancel();
thread?.Join();
cts?.Dispose();
autoResetEvent?.Dispose();
}
public static void ThreadJob(object obj)
{
var ct = (CancellationToken)obj;
while (!ct.IsCancellationRequested)
{
if(WaitHandle.WaitAny(new[] { tc.WaitHandle,autoResetEvent}) == 1)
{
// Do your stuff
}
}
}
public void PerformJobInThread()
{
autoResetEvent?.Set();
}
这样您的线程将一直运行,直到您调用 ThreadStop 方法(实际上,直到您取消 CancellationTokenSource),但您仍然可以控制何时“启用”它。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。