, - Tout;
:
using System;
using System.Collections.Generic;
using System.ComponentModel;
public static class QueuedBackgroundWorker
{
public static void QueueWorkItem<Tin, Tout>(
Queue<QueueItem<Tin>> queue,
Tin inputArgument,
Func<DoWorkArgument<Tin>, Tout> doWork,
Action<WorkerResult<Tout>> workerCompleted)
{
if (queue == null) throw new ArgumentNullException("queue");
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = false;
bw.WorkerSupportsCancellation = false;
bw.DoWork += (sender, args) =>
{
if (doWork != null)
{
args.Result = doWork(new DoWorkArgument<Tin>((Tin)args.Argument));
}
};
bw.RunWorkerCompleted += (sender, args) =>
{
if (workerCompleted != null)
{
workerCompleted(new WorkerResult<Tout>((Tout)args.Result, args.Error));
}
queue.Dequeue();
if (queue.Count > 0)
{
QueueItem<Tin> nextItem = queue.Peek();
nextItem.BackgroundWorker.RunWorkerAsync(nextItem.Argument);
}
};
queue.Enqueue(new QueueItem<Tin>(bw, inputArgument));
if (queue.Count == 1)
{
QueueItem<Tin> nextItem = queue.Peek() as QueueItem<Tin>;
nextItem.BackgroundWorker.RunWorkerAsync(nextItem.Argument);
}
}
}
public class DoWorkArgument<T>
{
public DoWorkArgument(T argument)
{
this.Argument = argument;
}
public T Argument { get; private set; }
}
public class WorkerResult<T>
{
public WorkerResult(T result, Exception error)
{
this.Result = result;
this.Error = error;
}
public T Result { get; private set; }
public Exception Error { get; private set; }
}
public class QueueItem<T>
{
public QueueItem(BackgroundWorker backgroundWorker, T argument)
{
this.BackgroundWorker = backgroundWorker;
this.Argument = argument;
}
public T Argument { get; private set; }
public BackgroundWorker BackgroundWorker { get; private set; }
}
:
private readonly Queue<QueueItem<int>> _workerQueue = new Queue<QueueItem<int>>();
private int _workerId = 1;
[Test]
public void BackgroundTest()
{
QueuedBackgroundWorker.QueueWorkItem(
this._workerQueue,
this._workerId++,
args =>
{
var currentTaskId = args.Argument;
var now = DateTime.Now.ToLongTimeString();
var message = string.Format("DoWork thread started at '{0}': Task Number={1}", now, currentTaskId);
return new { WorkerId = currentTaskId, Message = message };
},
args =>
{
var currentWorkerId = args.Result.WorkerId;
var msg = args.Result.Message;
var now = DateTime.Now.ToShortTimeString();
var completeMessage = string.Format(
"RunWorkerCompleted completed at '{0}'; for Task Number={1}, DoWork Message={2}",
now,
currentWorkerId,
msg);
}
);
}