问题:在安装过程中,文件和文件夹被创建、移动和重命名。服务也在安装过程中启动和停止,这可能导致一个或多个文件或文件夹出现锁定问题。我有一个避免大多数锁定情况的解决方案,但想要一种不会浪费时间或 CPU 的更好方法,并且可以防止用户尽可能多地处理 Abort/Retry/Ignore 对话框。
背景:在最佳方案中,处理服务启动和停止的逻辑以及其他将锁定文件和文件夹的操作将阻止锁定在安装程序的创建/移动/重命名部分发生时仍然存在。在这种情况下,我无法控制安装过程的这些部分,但是当文件或文件夹无法更改时,我确实需要尽可能避免显示用户错误对话框。
我无法简单地长时间循环,因为存在第三方应用程序锁定必要资源的合法错误情况,我们需要能够及时向用户显示此信息,并向他们显示有关违规进程的信息. 但是,我的用例中有很多误报,我想尽量减少用户干预。
我目前的解决方案看起来像这样:
private const int MaxRetry = 3;
private const int RetryDelayMs = 250;
private static bool DoAction(FileSystemAction action, String src, String dest = "")
{
bool retval = false;
bool inprogress = true;
// (Re)Attempt to perform the desired action until the user aborts.
while (inprogress)
{
try
{
// Automatically retry N times with a delay of M milliseconds.
// This is meant to reduce the number of times a user sees an error dialog.
var autoretry = true;
var retryCounter = 0;
while (autoretry)
{
try
{
// CODE: Attempt to perform the file system action.
// Only get here if we succeeded.
autoretry = false;
}
catch (Exception)
{
// If this operation failed, try a few times.
if (retryCounter >= MaxRetry)
throw;
retryCounter++;
Thread.Sleep(RetryDelayMs);
}
}
// If we get here without exception, success!
inprogress = false;
retval = true;
}
catch (Exception ex)
{
// Since there was an error, we now do the following:
// - Determine if locked files are the cause.
// - If locked files are the cause:
// - Show a custom Locked File dialog, providing information.
// - Otherwise:
// - Select message string based on action to inform the user.
// - Allow the user to Retry/Abort/Ignore the failed operation.
// CODE: Logic goes here.
}
}
return retval;
}
当我第一次编写这个逻辑时,我在这里浏览了几个处理锁定文件和失败文件系统操作的例子;但是,我对这个解决方案并不满意,因为它不会阻止用户在所有误报情况下(存在竞争条件)看到对话框。在不重写有问题的服务逻辑的情况下改进这一点有什么想法吗?