2

2 つのストリームがあり、1 つ目はプロセスのテーブルを表示し、2 つ目はそれらをカウントして表示します。最初に最初に起動し、次に 2 番目に起動します。

Thread t1 = new Thread(tmh1.FillTable);
Thread t2 = new Thread(tmh1.GetGeneralInfo);
t1.Start();
t2.Start();

スレッドで実行されるメソッドは次のとおりです。

public void FillTable()
{
    while (true)
    {
         lock (lockObj)
         {
            arr.Clear();
            arr.AddRange(Process.GetProcesses());
            TableFormatter.Line();
            TableFormatter.Row("Name", "ID", "threads quantity", "Start time");
            TableFormatter.Line();
          }
          Thread.Sleep(interval);
      }
}
public void GetGeneralInfo()
{
    while (true)
    {
        lock (lockObj)
        {
           Console.WriteLine(arr.Count.ToString());
        }
    Thread.Sleep(interval);
    }
}

そして結果:

0
-----------------------------------------------------------------------------
|     Name     |         ID       |  threads quantity|  Start time          |
-----------------------------------------------------------------------------

ただし、次のようにする必要があります。

-----------------------------------------------------------------------------
|     Name     |         ID       |  threads quantity|  Start time          |
-----------------------------------------------------------------------------
**68**

トレッドを正しい順序で実行するにはどうすればよいですか?

4

5 に答える 5

6

スレッドは並行して実行されるはずです。最初のスレッドが完了したときに 2 番目のスレッドが実行するタスクを実行したい場合は、単純に最初のスレッドに 2 番目のタスクも実行させます。

タスク並列ライブラリの手段を使用して、タスクを次々に実行することもできます。

Task.Factory.StartNew(() => tmh1.FillTable()).ContinueWith(() => tmh1.GetGeneralInfo(), TaskScheduler.FromCurrentSynchronizationContext());
于 2012-05-16T12:58:33.460 に答える
4

タスクを使用します。例えば:

Task.Factory.StartNew(tmh1.FillTable).ContinueWith(tmh1.GetGeneralInfo)

ただし、とにかく2つのスレッドが必要な理由は明確ではありません。以下も機能するはずです。

Thread t1 = new Thread(()=>{tmh1.FillTable; tmh1.GetGeneralInfo();});
t1.Start();
于 2012-05-16T13:02:49.437 に答える
3

This code is very odd and it is difficult to determine why you want to create 2 threads that run after each other.

Assuming that the desired effect is running two things at different times on a different thread, the simplest way to do it, assuming you can use C# 4 is to utilise the Task Parallel Library. An example of which is as follows:

        Task.Factory
            .StartNew(() => Console.WriteLine("This is the first"))
            .ContinueWith(t => Console.WriteLine("This is the second"));

        Console.ReadLine();

If you want to create threads manually you should read up on the signalling constructs

于 2012-05-16T13:03:26.927 に答える
0

ここでスレッドの使用は無意味であると言わざるを得ません。あなたが提示した以上のものがあると思います。おそらく、投稿を小さくするためにコードをトリミングしましたか?

とにかく、最小限の微調整とリファクタリングを必要とする解決策は、Monitor.Pulseandを使用することMonitor.Waitです。

public void FillTable()
{
    while (true)
    {
         Thread.Sleep(interval);
         lock (lockObj)
         {
            arr.Clear();
            arr.AddRange(Process.GetProcesses());
            TableFormatter.Line();
            TableFormatter.Row("Name", "ID", "threads quantity", "Start time");
            TableFormatter.Line();
            Monitor.Pulse(lockObj);
          }
      }
}

public void GetGeneralInfo()
{
    while (true)
    {
        lock (lockObj)
        {
           Monitor.Wait(lockObj);
           Console.WriteLine(arr.Count.ToString());
        }
    }
}

ただし、使用できる他のテクニックがあります。一般的なアプローチの 1 つは、生産者と消費者のパターンを使用することです。BlockingCollectionこれは、クラスを使用すると非常に簡単です。

private BlockingCollection<Process[]> queue = new BlockingCollection<Process[]>();

public void FillTable()
{
    while (true)
    {
         Thread.Sleep(interval);
         queue.Add(Process.GetProcesses());
    }
}

public void GetGeneralInfo()
{
    while (true)
    {
        Process[] processes = queue.Take();
        Console.WriteLine(processes.Length.ToString());
    }
}
于 2012-05-16T13:40:40.827 に答える
0

リセット イベントを使用してシグナリングを使用できます (C# の AutoResetEvent または ManualResetEvent を参照)。ただし、ロックで待機シグナルを呼び出すのは危険な場合があります (デッドロックなど)。

于 2012-05-16T12:59:24.577 に答える