0

私のコンソール アプリケーションでは、スレッド内でのイベントの同期が困難になります。

using System;
using System.Threading;
using System.Windows.Forms;

namespace ConsoleApplication1
{
    public class Example
    {
        private static Button _button;
        private static readonly EventWaitHandle Ewh = new EventWaitHandle(false, EventResetMode.ManualReset);
        private static readonly EventWaitHandle Btn = new EventWaitHandle(false, EventResetMode.ManualReset);

        [STAThread]
        public static void Main()
        {
            _button = new Button();
            _button.Click += _button_Click;
            for (int i = 0; i <= 0x4; i++)
            {
                var t = new Thread(ThreadProc);
                t.Start(i);
            }
            Console.WriteLine("Press ENTER to release a waiting thread.");
            Console.ReadLine();
            Ewh.Set();
            Console.ReadLine();
        }

        private static void _button_Click(object sender, EventArgs e)
        {
            Console.WriteLine(new Random().Next(0x1388));
            Thread.Sleep(10);
            Btn.Set();
        }

        public static void ThreadProc(object data)
        {
            _button.PerformClick();
            Btn.WaitOne();
            Btn.Reset();
            Console.WriteLine("Thread {0} blocks.", data);
            Ewh.WaitOne();
            Console.WriteLine("Thread {0} exits.", data);
        }
    }
}

アプリケーションは、いくつかの乱数の後にスレッド ブロックが続き、EventWaithandleデータ スレッドが終了した後、コンソールに出力されて結果を返します。

目的は、次のような方法でデータを印刷することです

*ランダムデータ

スレッドブロック

ランダムデータ

スレッドブロック

....

スレッドの終了

...*

サンプル出力

1234

スレッド 2 ブロック

2345

スレッド 0 ブロック

3456

スレッド 1 ブロック

....

スレッド 1 の終了

スレッド 4 終了

....

その方法でスレッドとスレッド内のイベントを同期する方法。

4

2 に答える 2

0

代わりに、タスク スケジューラと同期コンテキストを使用してください。メイン スレッドで同期コンテキストを作成し、メイン スレッドで実行するタスクに渡します。

于 2012-12-27T12:31:41.380 に答える
0

これが私のコードです。Btn には AutoResetEvent を使用します。また、Button を作成していて、バックグラウンド スレッドからアクセスしていることがわかります。このコードを削除し、代わりに ButtonClick メソッドを直接呼び出しました。結果のコードは次のとおりです。

using System;
using System.Threading;
using System.Windows.Forms;

namespace ConsoleApplication1
{
    public class Example
    {
        private static Button _button;
        private static readonly EventWaitHandle Ewh = new EventWaitHandle(true, EventResetMode.ManualReset);
        private static readonly EventWaitHandle Btn = new EventWaitHandle(true, EventResetMode.AutoReset);
        [STAThread]
        public static void Main()
        {
            Ewh.Reset();
            _button = new Button();
            _button.Click += _button_Click;
            for (int i = 0; i <= 0x4; i++)
                new Thread(ThreadProc).Start(i);
            Console.WriteLine("Press ENTER to release a waiting thread.");
            Console.ReadLine();
            Ewh.Set();
            Console.ReadLine();
        }

        private static void _button_Click(object sender, EventArgs e)
        {
            Console.WriteLine(new Random().Next(0x1388));
            Thread.Sleep(10);
        }

        public static void ThreadProc(object data)
        {
            Btn.WaitOne();
            Console.WriteLine("Thread {0} blocks.", data);
            _button.PerformClick();
            Btn.Set();
            Ewh.WaitOne();
            Console.WriteLine("Thread {0} exits.", data);
        }
    }
}
于 2012-12-27T14:15:06.793 に答える