1

非常に不自然な問題があります。

1つのメソッドと1つのフィールドしかないクラスがあるとします。好き:

public class WhereAmI
{
    public int Number = 0;
    public void Looping()
    {
         for (int i = 0; i < 100; i++)
        {
            Number = i;
            Sleep(10000);
        }
    }
}

私はあなたが期待する通常の方法で別のクラスからそれを呼び出します

WhereAmI wai = new WhereAmI();
wai.Looping();
int CurrentNumber = wai.Number;

私が欲しいのは、私が現在何番までいるかを確認し、それを画面に表示する方法です。上記と同様のことを試しましたが、コンパイラが完了するまでwai.Loopping()メソッドを通過しないため、これは機能しません。

新しいスレッドでこれを実行してから、クロススレッドの世界に入る必要があると思いますか?それから私は自分のデザインが間違っているに違いないと思いました、そして私はこれを複雑にしすぎました!

誰かがこれについて彼らの意見や提案を渡すことを気にしますか?

ありがとうございました

4

3 に答える 3

4

このコードがUIスレッドで実行されていると仮定すると、ループ内でUIを直接更新できます。ただし、UIコードをビジネスロジックと混合したくない場合(これは良い考えです)、はい、別のスレッドでこの処理を実行し、UIスレッドにこのオブジェクトを検査させるか、できればタスクとしてイベント通知を取得する必要があります進行します。

おそらく、BackgroundWorkerを使用して処理を処理することを検討する必要があります。このクラスを使用すると、このような処理タスクを簡単に作成でき、進行状況インジケーターをサポートするロジックが含まれます。

MSDNの記事のサンプルコードは、デザインサーフェスにドラッグアンドドロップして(WinFormsを使用していると仮定して)これを多く設定する方法と、BackgroundWorkerをプログレスバーにリンクする方法を示しています。

于 2012-10-22T12:57:43.247 に答える
1

ThreadPoolを使用してスレッド化を行う基本的な例を次に示します。

void Main()
{
   var pooling = new JustPooling();

   pooling.RunThread();

   Thread.Sleep(500);

   while (pooling.Operating)
   {
      Console.Write (" " + pooling.CurrentIndex);
      Thread.Sleep(500);
   }

   Console.Write(" Done");
   /* 1 1 2 2 2 3 3 3 4 4 4 5 5 5 Done */


}

// Define other methods and classes here

public class JustPooling
{
   public bool Operating { get; set; }
   public int CurrentIndex { get; set; }

   public void RunThread()
   {
       ThreadPool.QueueUserWorkItem(delegate
        {
            Operating = true;

            for ( int index = 0; index < 5; ++index )
            {
                ++CurrentIndex;
                Thread.Sleep( 1500 );
            }

            Operating = false;
        });
   }

}

クリティカルセクションのロックを使用したこの例を確認するには、ThreadPool、匿名デリゲート、およびロックを使用したC#マルチスレッドを参照してください。

于 2012-10-22T13:04:42.180 に答える
1

コールバックまたはイベントハンドラーを使用して、すべてを同じスレッドに保持します。

コールバック:

public void Looping(Action onIncrement)
{
   for (int i = 0; i < 100; i++)
   {
      Number = i;
      onIncrement();
      Sleep(10000);
   }
}

obj.Looping(() => Console.WriteLine(obj.Number));

イベントハンドラー:

public event EventHandler Increment;

public void Looping()
{
   for (int i = 0; i < 100; i++)
   {
      Number = i;
      if (Increment != null)
      {
          Increment(this, EventArgs.Empty);
      }
      Sleep(10000);
   }
}

obj.Increment += (s, e) => Console.WriteLine(obj.Number);
obj.Looping();
于 2012-10-22T13:07:14.573 に答える