加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – AutoResetEvent重置方法

发布时间:2020-12-15 21:16:39 所属栏目:百科 来源:网络整理
导读:超级简单的问题,但我只是想澄清一下.我希望能够使用AutoResetEvent重新启动一个线程,所以我将以下方法序列调用到我的AutoResetEvent. setupEvent.Reset(); setupEvent.Set(); 我知道这很明显,但是MSDN没有在他们的文档中声明Reset方法重新启动线程,只是它将
超级简单的问题,但我只是想澄清一下.我希望能够使用AutoResetEvent重新启动一个线程,所以我将以下方法序列调用到我的AutoResetEvent.

setupEvent.Reset();                   
setupEvent.Set();

我知道这很明显,但是MSDN没有在他们的文档中声明Reset方法重新启动线程,只是它将事件的状态设置为无信号.

更新:

是的,另一个线程正在等待WaitOne(),我假设当它被调用它将在它停止的确切点恢复,这是我不想要的,我希望它从头重新开始.以下来自this有价值资源的示例说明了这一点:

static void Main()
  {
    new Thread (Work).Start();

    _ready.WaitOne();                  // First wait until worker is ready
    lock (_locker) _message = "ooo";
    _go.Set();                         // Tell worker to go

    _ready.WaitOne();
    lock (_locker) _message = "ahhh";  // Give the worker another message
    _go.Set();
    _ready.WaitOne();
    lock (_locker) _message = null;    // Signal the worker to exit
    _go.Set();
  }

  static void Work()
  {
    while (true)
    {
      _ready.Set();                          // Indicate that we're ready
      _go.WaitOne();                         // Wait to be kicked off...
      lock (_locker)
      {
        if (_message == null) return;        // Gracefully exit
        Console.WriteLine (_message);
      }
    }
  }

如果我正确地理解了这个例子,请注意当线程发出信号时主线程将如何从它停止的地方恢复,但在我的情况下,我希望主线程从头开始重启.

更新2:

@Jaroslav Jandek – 它非常复杂,但基本上我有一个CopyDetection线程,它运行一个FileSystemWatcher来监视一个文件夹,查找被移动或复制到其中的任何新文件.我的第二个线程负责将该特定文件夹的结构复制到另一个文件夹中.所以我的CopyDetection线程必须阻止该线程在复制/移动操作进行时工作.操作完成后,CopyDetection线程将重新启动第二个线程,以便它可以使用新添加的文件重新复制文件夹结构.

更新3:

@ SwDevMan81 – 我实际上并没有想到这一点,除了一个警告之外,这会有用.在我的程序中,复制过程完成后,将复制正在复制的源文件夹.这就是为什么我必须在将新项目添加到源文件夹时阻止并重新启动第二个线程,因此它有可能正确地重新解析文件夹的新结构.

为了解决这个问题,我想可能会添加一个标志,表示删除源文件夹的内容是安全的.猜猜我可以将删除操作放在它自己的清理线程上.

@Jaroslav Jandek – 道歉,我认为随心所欲地重新启动一个线程是一件简单的事情.要回答你的问题,我不是删除源文件夹,只是它的内容,这是我的雇主的要求,不幸的是我无法改变.源文件夹中的文件正在被移动,但不是所有文件,只有被另一个进程正确验证的文件,其余文件必须被清除,即源文件夹被清空.此外,复制源文件夹结构的原因是某些文件包含在必须保留在目标目录中的非常严格的子文件夹层次结构中.再次抱歉让它变得复杂.所有这些机制都已到位,已经过测试并正在运行,这就是为什么我觉得不需要详细说明它们.我只需要检测何时添加新文件,这样我可以在复制/移动操作正在进行时正确暂停其他进程,然后我可以安全地复制源文件夹结构并恢复处理.

解决方法

因此,线程1监视器和线程2重复,而其他进程修改受监视的文件.

除了并发文件访问权限,您无法在更改后继续复制.因此,只有在修改之间有足够长的延迟时才会成功进行复制.由于您以块的形式进行复制,因此无法立即停止复制.

因此监视的结果应该是命令(文件复制,文件删除,文件移动等).
成功复制的结果应该是执行命令.

考虑到可能发生多个操作,您需要一个队列(或排队字典 – 仅对文件执行1个命令)的命令.

// T1:
somethingChanged(string path,CT commandType)
{
  commandQueue.AddCommand(path,commandType);
}

// T2:
while (whatever)
{
  var command = commandQueue.Peek();
  if (command.Execute()) commandQueue.Remove();
  else // operation failed,do what you like.
}

现在您可能会问如何创建一个线程安全的查询,但这可能属于另一个问题(Web上有很多实现).

EDIT(具有整个dir复制的无队列版本 – 可以与查询一起使用):
如果您不需要多个操作(例如,始终复制整个目录)并期望复制始终完成或失败并取消,您可以执行以下操作:

private volatile bool shouldStop = true;

// T1:
directoryChanged()
{
  // StopReplicating
  shouldStop = true;
  workerReady.WaitOne(); // Wait for the worker to stop replicating.

  // StartReplicating
  shouldStop = false;
  replicationStarter.Set();
}

// T2:
while (whatever)
{
  replicationStarter.WaitOne();

  ... // prepare,throw some shouldStops so worker does not have to work too much.

  if (!shouldStop)
  {
    foreach (var file in files)
    {
      if (shouldStop) break;

      // Copy the file or whatever.
    }
  }

  workerReady.Set();
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读