简体   繁体   English

如何在 C# 的主线程中生成工作线程并处理它们的输出?

[英]How to spawn worker threads and process their outputs in main thread in C#?

I want to implement the following functionality in C# console application:我想在 C# 控制台应用程序中实现以下功能:

  1. spawn several worker threads in main thread;在主线程中产生多个工作线程;
  2. each worker thread processes data and send string message to main thread periodically;每个工作线程处理数据并定期向主线程发送字符串消息;
  3. main thread processes messages and wait for all worker threads to finish;主线程处理消息并等待所有工作线程完成;
  4. main thread exit.主线程退出。

Now I'm using TPL, but I don't know how to send messages from worker threads to main thread.现在我正在使用 TPL,但我不知道如何从工作线程向主线程发送消息。 Thank you for help!谢谢你的帮助!

You could use a Producer / Consumer pattern with the TPL as demonstrated in this example on an MSDN blog .您可以将生产者/消费者模式与 TPL 结合使用,如MSDN 博客上的本示例所示

Or, you could kick it old-school and use signaling, see AutoResetEvent .或者,您可以将其踢成老式并使用信号,请参阅AutoResetEvent

Or if you care to work at a very low level, use Monitor.Pulse with Monitor.WaitOne (as demonstrated here ).或者,如果你愿意工作在一个非常低的水平,使用Monitor.PulseMonitor.WaitOne (如证明这里)。

Either way, you are looking for Synchronization, which you can read up on here .无论哪种方式,您都在寻找同步,您可以在此处阅读。


Other option, if you don't actually care what thread the update is running on, would be to take a delegate as an argument and print the update there, à la:其他选项,如果您实际上并不关心更新在哪个线程上运行,则将委托作为参数并在那里打印更新,à la:

static Task<string> ReadFile(string filename, Action<string> updateStatus)
{

    //do stuf synchronously
    return Task<string>.Factory.StartNew(() => {
        System.Threading.Thread.Sleep(1000);
        //do async stuff
        updateStatus("update message");
        //do other stuff
        return "The result";
    });
}

public static void Main(string[] args) 
{
    var getStringTask = ReadFile("File.txt", (update) => {
        Console.WriteLine(update)
    });
    Console.Writeline("Reading file...");
    //do other stuff here
    //getStringTask.Result will wait if not complete
    Console.WriteLine("File contents: {0}", getStringTask.Result);
}

would print:会打印:

Reading file...
update message
File contents: The result

The "update message" call to Console.WriteLine would still occur on the ThreadPool thread, but it may still fill your need.Console.WriteLine"update message"调用仍然会发生在ThreadPool线程上,但它可能仍然满足您的需要。

I would wrap the worker threads to their own Func or regular method with IEnumerable<string> as their return type.我会将工作线程包装到它们自己的Func或常规方法中,并使用IEnumerable<string>作为它们的返回类型。 Then I'll create a Task for each worker that call foreach on the Func /method and process their message.然后,我将为在Func /method 上调用foreach每个工作人员创建一个任务并处理他们的消息。

Here's a simple example using two regular methods.这是一个使用两种常规方法的简单示例。 Should the methods are arbitrary, you'll want to create a List<Task>如果方法是任意的,您将需要创建一个List<Task>

static void Main(string[] args)
{
    var task1 = Task.Factory.StartNew(()=>{foreach (var n in Back1(13)) Console.WriteLine("From Back 1, said "+n);});
    var task2 = Task.Factory.StartNew(() => { foreach (var n in Back2(5)) Console.WriteLine("From Back 2, said " + n); });
    task1.Wait();
    task2.Wait();
    Console.WriteLine("All done");
    Console.ReadLine();
}

static IEnumerable<string> Back1(int it)
{
    for (int i = 0; i < it; i++)
    {
        System.Threading.Thread.Sleep(100);
        yield return i +" of "+it;
    }

    yield return "I'm done";
}

static IEnumerable<string> Back2(int it)
{
    for (int i = 0; i < it; i++)
    {
        System.Threading.Thread.Sleep(150);
        yield return i +" of "+it;
    }

    yield return "I'm done";
}

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

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