[英]How can I decouple this C# worker thread code from the main thread for shared data variables?
为了更好的代码可读性,我怎么能修改下面的代码呢?
a)将“workThreadMethod()”移动到它自己的类中
b)此工作线程类中没有任何代码引用主“Program”类的静态变量
c)以上是主要的两个要求,但是我希望作为一个副作用,这将确保为了可测试性,工作者线程类方法将更容易测试并且理想地适合通过IOC进行测试(例如Ninject)概念[如果这没有意义,那么为了问题的目的忽略这一点]
我不确定要解决的主要挑战是如何处理原始线程和新线程之间的两个不同的共享变量(其中一个是新线程添加的ConcurrentQueue,另一个是原始线程的bool变量)线程用于指示新线程何时停止)
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Threading;
namespace TestConsoleApp
{
class Program
{
// Main Thread uses to indicate to New Thread to stop
private static bool _shouldStop = false;
// New Thread uses to pass back result to Main Thread
private static long _results = 0;
// Main Thread passes ongoing updates to New Thread via this queue
private static ConcurrentQueue<long> _workQueue = new ConcurrentQueue<long>();
static void Main(string[] args)
{
var p = new Program();
p.TestThreads();
}
public void TestThreads()
{
_shouldStop = false;
var workThread = new Thread(workThreadMethod);
workThread.Start();
for (int i = 0; i < 100; i++)
{
_workQueue.Enqueue(i); // Add test data to queue
Debug.WriteLine("Queue : " + i);
Thread.Sleep(10);
}
Thread.Sleep(5000);
_shouldStop = true;
workThread.Join();
Debug.WriteLine("Finished TestThreads. Result = " + _results);
}
// Dequeuer Methods
private void workThreadMethod()
{
// Update Summary
while (!_shouldStop)
{
if (_workQueue.Count == 0)
{
Thread.Sleep(10);
}
else
{
long currentValue;
bool worked = _workQueue.TryDequeue(out currentValue);
if (worked)
{
_results += currentValue;
Debug.WriteLine("DeQueue: " + currentValue);
}
}
}
}
}
}
这是一个关注点分离的练习,最初我会把这个程序分成一个work provider
和worker
。 提供者负责队列和执行控制,而工作人员应该进行计算。 以下代码是一个粗略的开始,但它应该让你去。
拆分这两个问题并使用构造函数注入已经支付了可测试性,您现在可以在不涉及Program
情况下完全测试Worker
。
注意:考虑到您的应用程序的进一步开发,我强烈建议您查看任务并行库 。 使用诸如TPL之类的库使您可以利用多核处理器,而无需处理线程分配和工作调度的复杂性。 这里讨论有关TPL的更多资源。
public interface IWorkProvider
{
bool ShouldStop { get; }
long? GetWork();
}
public class Program : IWorkProvider
{
// Main Thread uses to indicate to New Thread to stop
private static bool _shouldStop = false;
// Main Thread passes ongoing updates to New Thread via this queue
private static ConcurrentQueue<long> _workQueue = new ConcurrentQueue<long>();
public bool ShouldStop { get { return _shouldStop; } }
public long? GetWork()
{
long currentValue;
bool worked = _workQueue.TryDequeue(out currentValue);
if (worked)
return currentValue;
return null;
}
}
public class Worker
{
private long _results;
private readonly IWorkProvider _workProvider;
public long Results { get { return _results; }}
public Worker(IWorkProvider workProvider)
{
_workProvider = workProvider;
}
public void DoWork()
{
// Update Summary
while (!_workProvider.ShouldStop)
{
long? work = _workProvider.GetWork();
if (work.HasValue)
{
_results += work.Value;
Debug.WriteLine("DeQueue: " + work.Value);
}
else
{
Thread.Sleep(10);
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.