Design patterns c#方法循环和控制
Design patterns c#方法循环和控制,design-patterns,loops,methods,Design Patterns,Loops,Methods,我有一个方法要反复运行。我希望能够启动和停止此过程 我一直在使用这个模式进行一些套接字工作,我想知道我能做些什么改进 public delegate void VoidMethod(); public class MethodLooper { private VoidMethod methodToLoop; private volatile bool doMethod; private readonly object locker = new object();
我有一个方法要反复运行。我希望能够启动和停止此过程 我一直在使用这个模式进行一些套接字工作,我想知道我能做些什么改进
public delegate void VoidMethod();
public class MethodLooper
{
private VoidMethod methodToLoop;
private volatile bool doMethod;
private readonly object locker = new object();
private readonly Thread loopingThread;
public void Start()
{
if (!doMethod)
{
doMethod = true;
loopingThread.Start();
}
}
public void Stop()
{
if (doMethod)
{
doMethod = false;
loopingThread.Join();
}
}
public void ChangeMethod(VoidMethod voidMethod)
{
if (voidMethod == null)
throw new NullReferenceException("voidMethod can't be a null");
Stop();
lock (locker)
{
methodToLoop = voidMethod;
}
}
public MethodLooper(VoidMethod voidMethod)
{
if (voidMethod == null)
throw new NullReferenceException("voidMethod can't be a null");
methodToLoop = voidMethod;
loopingThread = new Thread(new ThreadStart(_MethodLoop));
}
private void _MethodLoop()
{
VoidMethod methodToLoopCopy;
while (doMethod)
{
lock (methodToLoop)
{
methodToLoopCopy = methodToLoop;
}
methodToLoopCopy();
}
}
}
你应该把doMethodToLoop表示为volatile。如MSDN中所述: volatile关键字表示程序中的某个字段可以被操作系统、硬件或并发执行线程等修改
我很赶时间,但您应该从打开代码的开关中检查。更安全的版本是这样做:
private readonly object m_locker = new object(); // readonly so it can never be null
private readonly Thread m_workerThread; // readonly so must set in constructor,
// and never can be null afterwards
private Action m_methodToRun;
private volatile bool m_keepGoing = true; // needs to be volatile or else you need to lock around accesses to it.
public Constructor()
{
m_workerThread = new Thread(ThreadWorker);
}
public void SetMethod(Action action)
{
lock(m_locker)
m_methodToRun = action;
}
private void ThreadWorker()
{
while(m_keepGoing)
{
// use a lock to take a local copy in case another thread sets m_methodToRun to null
// while we are processing things
Action methodLocal;
lock(m_locker)
methodLocal = m_methodToRun;
methodLocal(); // call it
// Note: Remember that the underlying method being pointed to must ALSO be
// thread safe. Nothing you do here can make up for that if it is not.
}
}
private void Stop()
{
m_keepGoing = false;
m_workerThread.Join(); // BLOCK and wait for it to finish
}
private void Start()
{
m_keepGoing = true;
m_workerThread.Start();
}
有关volatile与locking的详细信息,请参阅@Orion-我喜欢您提出了如果操作设置为null会发生什么的问题-如果您delagate()会发生null什么?会发生null引用异常:-)抱歉!修正了abelenky的错误-我很累-现在有Orionies建议的一些功能很稳定-如果你切换到安腾(Itanium)这样的CPU架构,没有volatile会让你头疼。