待定任务模式:稍后尝试模式

时间:2015-12-07 13:04:27

标签: c# multithreading threadpool

我正在使用多个FileSystemWatcher个对象来观看多个目录。

当我对已查看的文件夹执行复制和粘贴操作时,FileSystemWatcher会为每个创建的新文件引发Created事件文件,我捕获。

我使用并行为 n 的线程池来排队作业并控制我想要的线程数(我可以一次创建200个文件,但是,我只希望4个线程适用于)。 "的"意味着计算校验和:

private byte[] calculateChecksum(string frl)
{
    byte[] checksum = null;
    FileStream stream = null;
    try
    {
        stream = File.Open(frl, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
        MD5 md5 = MD5.Create();
        checksum = md5.ComputeHash(stream);

    }
    finally
    {
        stream.Close();
    }

    return checksum;
}

问题在于,有时当一个线程正在处理该作业(calculateChecksum方法)时,它会尝试访问文件,但是,有时文件正在使用中(我支持SO)。 / p>

我想设置一个解决方案,以解决这个问题告诉我:" 稍后再尝试"。

一种解决方案是,再次将线程池上的作业排入队列。问题是我不知道如何告诉 以后 。我认为这很重要,因为我不想让它呼吸并在短时间内休息并稍后再次尝试。

例如:

  • 在监视文件夹中创建的新文件。
  • FileSystemWatcher提出了一个事件。
  • 我在线程池中排队。
  • 作业崩溃,因为我想要访问的文件正被另一个进程使用。
  • 再次排队作业并等待60秒再试一次
  • 60秒后,作业再次崩溃,我希望作业再次入队并等待300秒
  • 300秒后,它再次尝试,并且能够正确计算校验和。

我不想要:等待300秒表示线程池的线程正忙。它不允许派遣其他排队的工作。

我不知道我是否已经清楚了。 任何想法

1 个答案:

答案 0 :(得分:2)

基本上你想要一个带定时器的重试模式。

你可以通过Polly轻松地做到这一点:

// Retry, waiting a specified duration between each retry
Policy
  .Handle<DivideByZeroException>()
  .WaitAndRetry(new[]
  {
    TimeSpan.FromSeconds(1),
    TimeSpan.FromSeconds(2),
    TimeSpan.FromSeconds(3)
  });

https://github.com/App-vNext/Polly

或者喜欢没有polly的人:

https://stackoverflow.com/a/1563234/1384539