Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.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
C# 挂起任务模式:稍后再试模式_C#_Multithreading_Threadpool - Fatal编程技术网

C# 挂起任务模式:稍后再试模式

C# 挂起任务模式:稍后再试模式,c#,multithreading,threadpool,C#,Multithreading,Threadpool,我使用了几个FileSystemWatcher对象来监视几个目录 当我在监视的文件夹上对多个文件执行复制和粘贴操作时,FileSystemWatcher会为我捕获的每个新创建的文件引发一个Created事件 我正在使用并发度为n的线程池,以便将作业排队,并控制有多少线程在it上工作(我可以一次创建200个文件,但是,我只希望有4个线程在it上工作)。“它”表示计算校验和: private byte[] calculateChecksum(string frl) { byte[] chec

我使用了几个
FileSystemWatcher
对象来监视几个目录

当我在监视的文件夹上对多个文件执行复制和粘贴操作时,
FileSystemWatcher
会为我捕获的每个新创建的文件引发一个
Created
事件

我正在使用并发度为n的线程池,以便将作业排队,并控制有多少线程在it上工作(我可以一次创建200个文件,但是,我只希望有4个线程在it上工作)。“”表示计算校验和:

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
method)时,它会尝试访问该文件,但有时该文件正在使用中(SO支持)

为了解决这个问题,我想制定一个解决方案,告诉我:“稍后再试”

一种解决方案是,在线程池中再次将作业排队。问题是我不知道以后怎么说。我相信这很重要,因为我不想让它呼吸和休息很短时间,然后再试一次

例如:

  • 在监视文件夹上创建的新文件
  • FileSystemWatcher
    引发事件
  • 我在线程池中将作业排队
  • 作业崩溃,因为我要访问的文件正被另一个进程使用
  • 再次将作业排队,并等待60秒重试
  • 60秒后,作业再次崩溃,我希望作业再次排队并等待300秒
  • 300秒后,它再次尝试,并且能够正确计算校验和
我不希望这样:等待300秒表示线程池中的线程正忙。它不允许分派其他排队作业

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

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

你可以用Polly轻松做到这一点:

// Retry, waiting a specified duration between each retry
Policy
  .Handle<DivideByZeroException>()
  .WaitAndRetry(new[]
  {
    TimeSpan.FromSeconds(1),
    TimeSpan.FromSeconds(2),
    TimeSpan.FromSeconds(3)
  });
//重试,在每次重试之间等待指定的持续时间
政策
.Handle()
.WaitAndRetry(新[]
{
时间跨度从秒(1),
时间跨度。从秒(2),
时间跨度。从秒(3)
});

或者像下面没有波利的话:


如果希望线程执行其他任务,以防文件被另一个进程持有,则可以使用
TaskCompletionSource
。但这需要在代码中使用async/await,这不是一件坏事。事实并非如此。使用
等待任务等待。延迟(300000)。好的。真是太棒了!我发现我可以制定一个行为准则。但是,我可以设置一个最多重试n次的行为,例如:“立即”,120秒后,以及300秒后的最后一次。此行为策略使池中的线程在120+300=420秒的时间内忙碌。我错了吗?你可以,使用带有超时取消的任务。