简体   繁体   English

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

[英]C# WPF Threading : How to Stop the newly created thread in a event function(Click on a button). without affecting the main thread

Here in the below code I want to stop the thread which is created in StartInvokeExplorer function.在下面的代码中,我想停止在StartInvokeExplorer function 中创建的线程。 Also the starter function in the StartInvokeExplorer is a keyhook function. StartInvokeExplorer 中的启动器StartInvokeExplorer也是一个 keyhook function。

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);
            }
        }

As from what I have understand, you want to stop the running thread.据我了解,您想停止正在运行的线程。 This is how.就是这样。

First, you need to create some stop logic.首先,您需要创建一些停止逻辑。 In your case, it would be some variable, like:在您的情况下,这将是一些变量,例如:

bool threadShouldRun;

and then inside your thread function, you should create a loop like:然后在你的线程 function 中,你应该创建一个循环,如:

void MyThreadFunc()
{
    while(threadShouldRun)
    {
        threadWork();
        Thread.Sleep(100);
    }
}

When you want to stop the thread, just set your threadShouldRun variable to false.当你想停止线程时,只需将你的threadShouldRun变量设置为 false。

Sleep is needed here.这里需要睡觉。 Without this, thread may use 100% of processor core.没有这个,线程可能会使用 100% 的处理器内核。

You can use an AutoResetEvent in conjunction with a CancellationToken .您可以将AutoResetEventCancellationToken结合使用。 Something along the line of (code not tested)类似于(代码未测试)的东西

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();
}

This way your thread will run until you call the ThreadStop method (actually, until you cancel your CancellationTokenSource) but you can still control when to "enable" it.这样,您的线程将一直运行,直到您调用 ThreadStop 方法(实际上,直到您取消 CancellationTokenSource),但您仍然可以控制何时“启用”它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM