4

C# コンソール アプリケーションに次の機能を実装したいと考えています。

  1. メイン スレッドで複数のワーカー スレッドを生成します。
  2. 各ワーカー スレッドはデータを処理し、文字列メッセージをメイン スレッドに定期的に送信します。
  3. メイン スレッドはメッセージを処理し、すべてのワーカー スレッドが終了するのを待ちます。
  4. メインスレッド出口。

現在 TPL を使用していますが、ワーカー スレッドからメイン スレッドにメッセージを送信する方法がわかりません。ご協力ありがとう御座います!

4

2 に答える 2

4

この例でMSDNブログに示されているように、TPLでプロデューサー/コンシューマーパターンを使用できます。

または、昔ながらの方法でシグナリングを使用することもできます。を参照してくださいAutoResetEvent

または、非常に低いレベルで作業する場合は、で使用Monitor.PulseしますMonitor.WaitOneここで示すように)。

いずれにせよ、あなたは同期を探しています。それはここで読むことができます。


他のオプションは、更新が実行されているスレッドを実際に気にしない場合は、引数としてデリゲートを取り、そこに更新を出力することです。

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);
}

印刷します:

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

"update message"呼び出しConsole.WriteLineは引き続きスレッドで発生しThreadPoolますが、それでもニーズを満たす可能性があります。

于 2012-11-21T02:37:07.913 に答える
1

ワーカースレッドを、リターンタイプとして独自のFuncメソッドまたは通常のメソッドにラップします。次に、/ methodIEnumerable<string>を呼び出してメッセージを処理する、ワーカーごとにタスクを作成します。foreachFunc

これは、2つの通常の方法を使用した簡単な例です。メソッドが任意の場合は、を作成する必要があります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";
}
于 2012-11-21T02:35:51.833 に答える