Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns c#方法循环和控制_Design Patterns_Loops_Methods - Fatal编程技术网

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会让你头疼。