1

我有两个程序:带有 .NET 2.0、C# 和 VS2010 的 WinformApplication 和 ConsoleApplication。

两个程序与 backgroundworker 和 EventWaitHandle 有相同的任务。

  1. 创建BGW
  2. 做工作
  3. RunWorkerCompleted { .. event.Set(); .. }
  4. 等待 event.waitone()

控制台应用程序运行良好。但是,Forms 应用程序不起作用。这是完整的代码。你能试试,让我知道是什么问题。

这是 WinFormApplication 代码:

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

这是 ConsoleApplication 代码:

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

0 回答 0