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秒后,它再次尝试,并且能够正确计算校验和
任何想法基本上你想要一个带计时器的重试模式 你可以用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秒的时间内忙碌。我错了吗?你可以,使用带有超时取消的任务。