Question

I have two programs : WinformApplication and ConsoleApplication with .NET 2.0 , C#, and VS2010.

Two programs has same taks with backgroundworker and EventWaitHandle.

  1. Create BGW
  2. DoWork
  3. RunWorkerCompleted { .. event.Set(); .. }
  4. Wait event.waitone()

Console apps works fine. However, Forms apps doesn't work. Here is full code. Can you try it and let me know what is the problem.

Here is WinFormApplication Code :

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

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        ProducerConsumerQueue[] q = new ProducerConsumerQueue[51];

        public Form1()
        {
            InitializeComponent();
            SetMinThreads();

            for (int i = 0; i < 51; i++)
                q[i] = new ProducerConsumerQueue(i);

            ReadyToWork();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

        private void SetMinThreads()
        {
            int workerT, portT;
            int minRequire = 51 + 5;

            ThreadPool.GetMaxThreads(out workerT, out portT);
            ThreadPool.GetMinThreads(out workerT, out portT);

            if (workerT < minRequire)
            {
                int inc = minRequire - workerT;
                workerT += inc;
            }

            ThreadPool.SetMinThreads(workerT, portT);
            Console.WriteLine(string.Format("Min: worker - {0}, port - {1}", workerT, portT));
        }

        private void ReadyToWork()
        {
            for (int i = 0; i < 51; i++)
                q[i].ReadParamFromController(true);

            for (int i = 0; i < 51; i++)
                q[i].ReadParamFromController(false);
        }
    }

    class ProducerConsumerQueue
    {
        EventWaitHandle _wh = new ManualResetEvent(false);
        int _id;
        public ProducerConsumerQueue(int id)
        {
            _id = id;
        }

        public void ReadParamFromController(bool isStart)
        {
            if (isStart)
            {
                {
                    _wh = new ManualResetEvent(false);

                    BackgroundWorker bwReadFromController = new BackgroundWorker();
                    bwReadFromController.WorkerSupportsCancellation = true;
                    bwReadFromController.DoWork += new DoWorkEventHandler(bwReadFromController_DoWork);
                    bwReadFromController.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwReadFromController_RunWorkerCompleted);
                    bwReadFromController.RunWorkerAsync();
                }
            }
            else
            {
                _wh.WaitOne();
            }
        }

        private void bwReadFromController_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if ((e.Cancelled == true))
            {
                Console.WriteLine("Cancelled task: ");
            }
            else if (!(e.Error == null))
            {
                Console.WriteLine("Error task: ");
            }
            else
            {
                Console.WriteLine("Performing Done: " + _id);
            }

            _wh.Set();

            ((BackgroundWorker)sender).Dispose();
            GC.Collect();
        }

        private void bwReadFromController_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            const int readFromControllerCount = 25;

            for (int i = 0; i < readFromControllerCount; i++)
            {
                if ((worker.CancellationPending == true))
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    // Do something
                    System.Threading.Thread.Sleep(10);
                }
            }
        }
    }
}

Here is ConsoleApplication Code :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main()
        {
            DateTime dt = DateTime.Now;
            Console.WriteLine(string.Format("start {0}", dt.ToString()));

            SetMinThreads();

            ProducerConsumerQueue[] q = new ProducerConsumerQueue[51];
            for (int i = 0; i < 51; i++)
                q[i] = new ProducerConsumerQueue(i);

            for (int i = 0; i < 51; i++)
                q[i].ReadParamFromController(true);// = new ProducerConsumerQueue();

            dt = DateTime.Now;
            Console.WriteLine(string.Format("Read Start {0}", dt.ToString()));

            for (int i = 0; i < 51; i++)
                q[i].ReadParamFromController(false);// = new ProducerConsumerQueue();

            Console.WriteLine();

            dt = DateTime.Now;
            Console.WriteLine(string.Format("Workers complete!  {0}", dt.ToString()));

            // Exiting the using statement calls q's Dispose method, which
            // enqueues a null task and waits until the consumer finishes.

            Console.ReadLine();
        }

        static private void SetMinThreads()
        {
            int workerT, portT;
            int minRequire = 51 + 5;

            ThreadPool.GetMaxThreads(out workerT, out portT);
            ThreadPool.GetMinThreads(out workerT, out portT);

            if (workerT < minRequire)
            {
                int inc = minRequire - workerT;
                workerT += inc;
            }

            ThreadPool.SetMinThreads(workerT, portT);
            Console.WriteLine(string.Format("Min: worker - {0}, port - {1}", workerT, portT));
        }
    }

    class ProducerConsumerQueue
    {
        EventWaitHandle _wh = new ManualResetEvent(false);
        int _id;
        public ProducerConsumerQueue(int id)
        {
            _id = id;
        }

        public void ReadParamFromController(bool isStart)
        {
            if (isStart)
            {
                {
                    _wh = new ManualResetEvent(false);

                    BackgroundWorker bwReadFromController = new BackgroundWorker();
                    bwReadFromController.WorkerSupportsCancellation = true;
                    bwReadFromController.DoWork += new DoWorkEventHandler(bwReadFromController_DoWork);
                    bwReadFromController.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwReadFromController_RunWorkerCompleted);
                    bwReadFromController.RunWorkerAsync();
                }
            }
            else
            {
                _wh.WaitOne();
            }
        }

        private void bwReadFromController_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if ((e.Cancelled == true))
            {
                Console.WriteLine("Cancelled task: ");
            }
            else if (!(e.Error == null))
            {
                Console.WriteLine("Error task: ");
            }
            else
            {
                Console.WriteLine("Performing Done: " + _id);
            }

            _wh.Set();

            ((BackgroundWorker)sender).Dispose();
            GC.Collect();
        }

        private void bwReadFromController_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            const int readFromControllerCount = 1;

            for (int i = 0; i < readFromControllerCount; i++)
            {
                if ((worker.CancellationPending == true))
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    //Console.WriteLine("Performing tasks: " + i);
                    System.Threading.Thread.Sleep(10);
                }
            }
        }
    }
}

No correct solution

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