【发布时间】:2018-08-08 08:54:57
【问题描述】:
编辑:我已从 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();
}
}
}
当我运行程序时,线程未启动:
线程状态:未启动 输入命令行(开始/等待/设置/状态/退出)启动线程后,事情变得很奇怪。 ThreadState 立即从 Running 变为 WaitSleepJoin。这是什么原因?我认为线程将保持在运行状态,直到我们调用方法 WaitOne()。
编辑:线程启动,其ThreadState 逻辑上是Running
然后当我输入Wait时,线程停留在WaitSleepJoin,但引擎继续运行。
编辑:我现在遇到的问题是如何阻止它?当我打电话时
Engine.ThreadHandle.WaitOne(Timeout.Infinite);
线程继续运行:
线程状态:未启动 输入命令行(开始/等待/设置/状态/退出) 开始 线程状态:正在运行 输入命令行(开始/等待/设置/状态/退出) 这个引擎辛苦了!!! 地位 >跑步 线程状态:正在运行 输入命令行(开始/等待/设置/状态/退出) 这个引擎辛苦了!!! 等待 线程状态:正在运行最后,当我输入 Set 时,线程永远不会回到运行状态。
我的问题仍然是:
- 如何中断线程
Enginebay 调用方法WaitOne()? - 之后如何恢复?
【问题讨论】:
-
引擎线程位于
WaitSleepJoin中,因为您在其中有Sleep命令。您的引擎线程需要调用 Wait one - 现在是您的“主”控制台线程执行此操作... -
谢谢你 fredrik,我已经添加了 ThreadHandle.WaitOne();在我的
Engine循环中,但引擎线程在启动后不断更改为WaitSleepJoin -
它会继续这样做,因为它正在睡觉......首先在
.Sleep(),然后在WaitOne()。 -
我删除了
.Sleep(5000),它现在一直在运行,但仍然无法暂停。 -
Run() 方法中的代码非常非常慢。一旦你让它运行,它将运行相当长的时间,似乎没有任何影响。您需要对其进行调整以使其与您的耐心兼容,减少循环,使其永远不会超过 50 毫秒。
标签: c# multithreading resume manualresetevent