[英]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時,線程永遠不會回到運行狀態。
我的問題仍然是:
WaitOne()
的線程Engine
托架? 當代碼執行之后(兩個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.