【发布时间】:2020-07-29 00:58:38
【问题描述】:
我还在学习线程,但下面的代码有问题。抱歉,如果这个问题之前出现过,我只是不明白为什么这段代码不起作用。 我简化了代码:
static EventWaitHandle waitH; // AutoResetEvent, wait for signal
static bool whExit; // signal to exit waiting
static Queue<string> str; // waiting line (example values)
static Queue<int> num; //
static void Main(string[] args)
{
waitH = new AutoResetEvent(false); // initialize waiter
str = new Queue<string>();
num = new Queue<int>();
Thread thr = new Thread(new ThreadStart(Waiter)); // waiting in another thread
thr.Start(); // start the waiting thread
for(short i = 0; i < 10; i++)
{
str.Enqueue(string.Format($"{(char)(i + 65)}")); // add something to queue
num.Enqueue(i); // add a number to test incrementing
waitH.Set(); // signal to start the "long processing"
}
}
static void Waiter()
{
while(!whExit)
{
waitH.WaitOne(); // wait for signal
WriteToConsole(); // start the long processing on another thread
}
}
static void WriteToConsole()
{
// threadstart with parameters
// action: void delegate
// get 2 values from waiting line
var f = new ParameterizedThreadStart(obj =>
new Action<string, int>(ConsoleWriter)
(str.Dequeue(), num.Dequeue())); // it's thread safe, because FIFO?
Thread thr = new Thread(f);
thr.IsBackground = true; // close thread when finished
thr.Start();
}
// print to console
static void ConsoleWriter(string s, int n)
{
Console.WriteLine(string.Format($"{s}: {++n}")); // easy example
}
它在 Main 的循环中停止。 我认为问题是:首先调用 Thread.Start() ,但它需要更改 Thread 的状态并加入“需要处理”队列,这需要时间。 Main 的循环已在运行,无需等待信号。
我用双向信号解决了这个问题:在循环中的 waitH.Set() 之后使用了另一个暂停信号 AutoResetEvent (WaitOne),并在完成 Console.WriteLine() 后发出信号。
我对这个解决方案并不真正感到自豪,因为如果我这样做,程序就会失去“线程”、并行或同步的方法。 这是一个例子,我想在不同的线程上同时运行长时间的计算。
如果我看到输出,那是我做错了一个适合书本的示例:
输出: 答:1 乙:2 有时 乙:2 答:1
预期输出: 答:1 乙:2 C: 3 D: 4 E:5 女:6 克:7 高:8 我:9 J:10
有什么优雅的方法可以解决这个问题吗?也许使用锁等。
任何讨论将不胜感激。 谢谢!
【问题讨论】:
标签: c# multithreading parallel-processing locking autoresetevent