簡體   English   中英

C#使用ManualResetEvent啟動停止線程

[英]C# Start Stop Thread with ManualResetEvent

編輯:我從Run()方法中刪除了.Sleep(5000) ,並用模擬復雜計算的雙循環替換了它。

我想了解如何使用ManualResetEvent控制線程? 我寫了應該啟動,停止和恢復前台線程的那段簡單代碼,但是它沒有按預期工作。

using System;
using System.Threading;

namespace ThreadHandler
{
    public class Engine
    {
        public static ManualResetEvent ThreadHandle;
        public static void Run()
        {
            Random rng = new Random();
            ThreadHandle = new ManualResetEvent(true);
            while (true)
            {
                ThreadHandle.WaitOne();
                for (int i = Int32.MaxValue; i > 0; i--)
                {
                    for (int j = 0; j < rng.Next(); j++)
                    {
                        int res;
                        int div =    
Math.DivRem(Math.Abs(Convert.ToInt32(Math.Floor(Math.Log(rng.NextDouble()) / 
Math.Log(rng.NextDouble())))),                           
Math.Abs(Convert.ToInt32(Math.Floor(Math.Log(rng.NextDouble()) /Math.Log(rng.NextDouble())))) + 1, out res);
                        double calc = Math.Sin(Math.Sqrt(div)) * Math.Cos(Math.Sqrt(res));
                    }
                    if (i % 500 == 0)
                        Console.WriteLine("This engine is working hard!!!");
                }
            }
        }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            Thread engine = new Thread(Engine.Run);
            int cnt = 100;
            while (cnt-- > 0)
            {
                Console.WriteLine("\nThread status: " +  engine.ThreadState);
                Console.WriteLine("Enter command line (Start/Wait/Set/Status/Quit)");
                string cmd = Console.ReadLine();
                switch(cmd.ToUpper())
                {
                    case "START":
                        engine.Start();
                        break;
                    case "WAIT":
                        Engine.ThreadHandle.WaitOne(Timeout.Infinite);
                        break;
                    case "SET":
                        Engine.ThreadHandle.Set();
                        break;
                    case "STATUS":
                        Console.WriteLine("  >" + engine.ThreadState);
                        break;
                    case "QUIT":
                        cnt = 0;
                        break;
                    default:
                        Console.WriteLine("Unknown command");
                        break;
                }
            }
            engine.Abort();
        }
    }
}

當我運行程序時,線程未啟動:

Thread status: Unstarted
    Enter command line (Start/Wait/Set/Status/Quit)

啟動線程后,事情變得很奇怪。 ThreadState立即從Running更改為WaitSleepJoin。 是什么原因呢? 我以為線程將保持其運行狀態,直到我們調用方法WaitOne()為止。

編輯:線程啟動,並且其ThreadState在邏輯上正在Running

Thread status: Unstarted
Enter command line (Start/Wait/Set/Status/Quit)
start

Thread status: Running
Enter command line (Start/Wait/Set/Status/Quit)
This engine is working hard!!!
status
  >Running

然后,當我鍵入Wait時,線程將停留在WaitSleepJoin中,但引擎將繼續運行。

編輯:我現在遇到的問題是如何停止它? 當我打電話

Engine.ThreadHandle.WaitOne(Timeout.Infinite);

線程繼續運行:

Thread status: Unstarted
Enter command line (Start/Wait/Set/Status/Quit)
start

Thread status: Running
Enter command line (Start/Wait/Set/Status/Quit)
This engine is working hard!!!
status
  >Running

Thread status: Running
Enter command line (Start/Wait/Set/Status/Quit)
This engine is working hard!!!
wait

Thread status: Running

最終,當我鍵入Set時,線程永遠不會回到運行狀態。

我的問題仍然是:

  1. 如何中斷調用方法WaitOne()的線程Engine托架?
  2. 之后如何恢復?

當代碼執行之后(兩個for循環)時,您的WaitOne()將永遠不會像在主循環中那樣工作。
您需要將其向下移動:

while (true)
{
    for (int i = Int32.MaxValue; i > 0; i--)
    {
        for (int j = 0; j < rng.Next(); j++)
        {
            ThreadHandle.WaitOne();
            // ...
        }

        if (i % 500 == 0)
            Console.WriteLine("This engine is working hard!!!");
    }
}

結果

Thread status: WaitSleepJoin
Enter command line (Start/Wait/Set/Status/Quit)

注意
我相信您會錯過使用ManualResetEvent因為需要等待的人(在您的情況下為Thread)需要WaitOne方法,但是您要調用它兩次。 您可能應該使用布爾值向線程發出信號,通知它應該啟動WaitOne

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM