我需要设计完美的工作线程方法。该方法必须执行以下操作:
主线程将字符串添加到队列并发出信号线程方法以继续并完成工作。
我希望您能为我提供所需同步对象的模板。
class MyClass, IDisposable
{
// Thread safe queue from third party
private ThreadSafeQueue<string> _workerQueue;
private Thread _workerThread;
public bool Initialize()
{
_workerThread = new Thread(WorkerThread).Start();
}
public AddTask(string object)
{
_workerQueue.Enqueue(object);
// now we must signal worker thread
}
// this is worker thread
private void WorkerThread()
{
// This is what worker thread must do
List<string> objectList = _workerQueue.EnqueAll
// Do something
}
// Yeap, this is Dispose
public bool Dispose()
{
}
}
答案 0 :(得分:2)
尝试这样的事情。使用类型字符串进行实例化并为其指定一个处理字符串的委托:
public class SuperQueue<T> : IDisposable where T : class
{
readonly object _locker = new object();
readonly List<Thread> _workers;
readonly Queue<T> _taskQueue = new Queue<T>();
readonly Action<T> _dequeueAction;
/// <summary>
/// Initializes a new instance of the <see cref="SuperQueue{T}"/> class.
/// </summary>
/// <param name="workerCount">The worker count.</param>
/// <param name="dequeueAction">The dequeue action.</param>
public SuperQueue(int workerCount, Action<T> dequeueAction)
{
_dequeueAction = dequeueAction;
_workers = new List<Thread>(workerCount);
// Create and start a separate thread for each worker
for (int i = 0; i < workerCount; i++)
{
Thread t = new Thread(Consume) { IsBackground = true, Name = string.Format("SuperQueue worker {0}",i )};
_workers.Add(t);
t.Start();
}
}
/// <summary>
/// Enqueues the task.
/// </summary>
/// <param name="task">The task.</param>
public void EnqueueTask(T task)
{
lock (_locker)
{
_taskQueue.Enqueue(task);
Monitor.PulseAll(_locker);
}
}
/// <summary>
/// Consumes this instance.
/// </summary>
void Consume()
{
while (true)
{
T item;
lock (_locker)
{
while (_taskQueue.Count == 0) Monitor.Wait(_locker);
item = _taskQueue.Dequeue();
}
if (item == null) return;
// run actual method
_dequeueAction(item);
}
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
// Enqueue one null task per worker to make each exit.
_workers.ForEach(thread => EnqueueTask(null));
_workers.ForEach(thread => thread.Join());
}
}
答案 1 :(得分:1)
我认为您应该考虑使用BackgroundWorker
课程,这可能符合您的需求。
答案 2 :(得分:1)
听起来像BlockingQueue就是你需要的。
答案 3 :(得分:1)
你应该看一下新的.Net 4 System.Collections.Concurrent Namespace。另外this little example应该可以帮助您更好地理解如何使用它。
答案 4 :(得分:1)
您所描述的内容最好用生产者 - 消费者模式来完成。使用阻塞队列最容易实现此模式。如果您使用的是.NET 4.0,那么您可以利用BlockingCollection类。以下是我看到您的代码工作的方式。在以下示例中,我使用null
值作为sentinel来优雅地结束使用者,但您也可以利用CancellationToken
方法上的Take
参数。
public class MyClass : IDisposable
{
private BlockingCollection<string> m_Queue = new BlockingCollection<string>();
public class MyClass()
{
var thread = new Thread(Process);
thread.IsBackground = true;
thread.Start();
}
public void Dispose()
{
m_Queue.Add(null);
}
public void AddTask(string item)
{
if (item == null)
{
throw new ArgumentNullException();
}
m_Queue.Add(item);
}
private void Process()
{
while (true)
{
string item = m_Queue.Take();
if (item == null)
{
break; // Gracefully end the consumer thread.
}
else
{
// Process the item here.
}
}
}
}