.NET 2.0、C#、および VS2010 を使用した WinformApplication と ConsoleApplication の 2 つのプログラムがあります。
2 つのプログラムは、backgroundworker と EventWaitHandle のタスクが同じです。
- BGW の作成
- 仕事する
- RunWorkerCompleted { .. event.Set(); ..}
- 待機 event.waitone()
コンソール アプリは問題なく動作します。ただし、フォーム アプリは機能しません。ここに完全なコードがあります。試してみて、何が問題なのか教えてください。
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);
}
}
}
}
}