我的Win32应用程序在运行时在指定的临时文件夹中执行大量的磁盘操作,严重的重新devise是不可能的。
一些客户端有防病毒软件扫描相同的临时目录(它只是扫描一切)。 我们试图说服他们禁用它 – 这是行不通的,所以也不可能。
每隔一段时间(对于每一千个文件操作都有一次),我的应用程序试图对由防毒软件打开的文件执行操作,因此被操作系统locking。 发生共享冲突并导致我的应用程序中出现错误。 平均每三分钟发生一次。
在大多数典型情况下,临时文件夹最多可以包含10万个文件,所以我不喜欢让它们随时打开的想法,因为这可能会导致在某些边缘条件下耗尽资源。
是否有一个合理的策略,我的应用程序对所需文件被locking的情况作出反应? 也许这样?
for( int i = 0; i < ReasonableNumber; i++ ) { try { performOperation(); // do useful stuff here break; } catch( ... ) { if( i == ReasonableNumber - 1 ) { throw; //not to hide errors if unlock never happens } } Sleep( ReasonableInterval ); }
这是一个可行的策略吗? 如果是这样,应用程序重试多less次和多久? 如果有什么更好的想法?
我曾经使用Symantec和AVG制作的防病毒软件,导致文件无法打开。
我们在赛门铁克2002年的时间框架中遇到的一个常见问题是MSDev6,当时文件按照这个顺序更新:
在步骤5和步骤6之间会出现问题。赛门铁克会采取一些措施来减缓删除操作,从而防止创建具有相同名称的文件(CreateFile返回ERROR_DELETE_PENDING)。 MSDev6将无法注意到 – 意味着第6步失败。 第7步仍然发生。 原件的删除最终会结束。 所以文件不再存在于磁盘上!
使用AVG,我们遇到了间歇性问题,能够打开刚被修改的文件。
我们的解决方案就像在问题中一样,是一个合理的循环。 我们的循环数是5。
一个在扫描文件时锁定文件的恶毒扫描程序是非常糟糕的。 有virusscanners这个坏客户的客户需要更换他们的大脑… 😉
好吧,足够的咆哮。 如果一个文件被其他进程锁定,那么你可以像你所建议的那样使用“再试一次”策略。 OTOH,你真的需要关闭然后重新打开这些文件吗? 难道你不能让他们打开,直到你的过程完成? 一个提示:当您尝试重新打开文件时,添加一个延迟(睡眠)。 大约100毫秒应该是足够的。 如果virusscanner保持文件打开,那么这是一个真正的坏的扫描仪。 扫描仪不好的客户应该看到他们会看到的异常信息。 通常情况下,最多尝试三次… – >打开,失败再试,第二次失败再试一次,第三次失败只是崩溃。
请记住以用户友好的方式崩溃。
取决于你的文件有多大,但是对于10s到100s的Kb,我发现5个100ms(0.1秒)就足够了。 如果偶尔碰到这个错误,请加倍等待,但是YMMV 。
如果你在代码中有几个地方需要这样做,我可以建议采取一种功能性的方法:
using System; namespace Retry { class Program { static void Main(string[] args) { int i = 0; Utils.Retry(() => { i = i + 1; if (i < 3) throw new ArgumentOutOfRangeException(); }); Console.WriteLine(i); Console.Write("Press any key..."); Console.ReadKey(); } } class Utils { public delegate void Retryable(); static int RETRIES = 5; static int WAIT = 100; /*ms*/ static public void Retry( Retryable retryable ) { int retrys = RETRIES; int wait = WAIT; Exception err; do { try { err = null; retryable(); } catch (Exception e) { err = e; if (retrys != 1) { System.Threading.Thread.Sleep(wait); wait *= 2; } } } while( --retrys > 0 && err != null ); if (err != null) throw err; } } }
你可以改变你的应用程序,所以你不释放文件句柄? 如果您自己锁定文件,antivir应用程序将无法扫描它。
否则像你这样的策略会有所帮助,因为它只会降低概率,但不能解决问题。
严重的问题。 大多数想法都是我不想要的方向(例如重新设计)。
我不知道您的目录中有多少个文件,但是如果没有那么多,您可以通过在程序运行时保持所有文件打开并锁定来解决您的问题。
这样病毒扫描程序将无法再中断您的文件访问。
如果有其他进程的可能性 – 无论是防病毒软件,备份工具还是用户自己 – 都可以打开文件,那么您必须对此进行编码。
只要ReasonableNumber
足够大,你的解决方案虽然也许不是最优雅的,但一定会起作用的 – 以前我用10作为合理的数字。 我当然不会走得更高,你可以得到一个较低的值,如5。
睡眠的价值? 最多100ms或200ms
请记住,大部分时间你的应用程序将首次获得文件。