Question

In my console application, Synchronizing the events within in thread makes difficult.

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

Application gives result as some random numbers followed by thread blocks and after signaling EventWaithandle data threads are exited printed on console.

aim is to print the data by following manner like

*random data

thread Block

random data

thread Block

....

thread exiting

...*

Sample output

1234

Thread 2 Blocks

2345

Thread 0 Blocks

3456

Thread 1 Blocks

....

Thread 1 exiting

Thread 4 Exiting

....

How to synchronize thread and event inside thread in that manner.

Was it helpful?

Solution

Here is my code. It uses the AutoResetEvent for the Btn. Also, I see that you are creating Button and access it from the background thread. I removed this code and instead called the ButtonClick method directly. Here is the resulting code:

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

OTHER TIPS

Use Task Schedulers and Synchronization Context instead. Create a Synchronization Context in the Main thread and pass it to the task that you want to execute in the main thread.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top