微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C# WPF 线程:如何在事件函数中停止新创建的线程单击按钮不影响主线程

如何解决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% 的处理器内核。

,

您可以将 AutoResetEventCancellationToken 结合使用。沿线的东西(代码未测试)

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 举报,一经查实,本站将立刻删除。