2

我有一个进程 A 读取由其他进程 B 生成的一些数据。数据通过文件系统“交换”。为确保文件存在,进程 A 当前检查文件是否存在,如下所示:

while (!File.Exists(FileLocation))
{
    Thread.Sleep(100);
} 

这似乎只有 99% 的时间有效。另外 1% 的时间,进程 A 确定文件存在,但进程 B 尚未写入所有内容(即丢失了一些数据)。

是否有另一种更简单的方法可以使上述情况更加防弹?谢谢。

4

4 回答 4

3

是否有另一种更简单的方法可以使上述情况更加防弹?

您可以使用 aMutex进行可靠的进程间同步。另一种可能性是使用FileSystemWatcher.

于 2013-02-22T13:14:11.037 回答
3

确定文件存在后,您可以尝试以独占方式打开文件,如果另一个进程仍然打开该文件,则会失败:

try
{
   File.Open("foo",FileMode.Open,FileAccess.Read,FileShare.None);
}
catch(IOException ex)
{
   // go back to 
}
于 2013-02-22T13:15:54.280 回答
1

鉴于您说您可以更改两个进程的代码,您可以使用 EventWaitHandle 在进程之间进行通信。

在创建文件的程序中,在 Main() 方法中,您可以创建一个 EventWaitHandle 并保留它直到程序结束。您需要在程序中传递 EventWaitHandle 对象,以便它可用于创建文件的代码位(或提供一些方法,文件创建代码可以调用以设置事件)。

using (EventWaitHandle readySignaller = new EventWaitHandle(false, EventResetMode.ManualReset, "MySignalName"))
{
    // Rest of program goes here...
    // When your program creates the file, do this:

    readySignaller.Set();
}

然后在等待文件的程序中有一些这样的代码:

// Returns true if the wait was successful.
// Once this has returned true, it will return false until the file is created again.

public static bool WaitForFileToBeCreated(int timeoutMilliseconds) // Pass Timeout.Infinite to wait infinitely.
{
    using (EventWaitHandle readySignaller = new EventWaitHandle(false, EventResetMode.ManualReset, "MySignalName"))
    {
        bool result = readySignaller.WaitOne(timeoutMilliseconds);

        if (result)
        {
            readySignaller.Reset();
        }

        return result;
    }
}

注意:如果我们成功等待,请注意我正在重置信号,它将保持重置,直到其他进程再次设置它。如果需要,您可以以不同的方式处理逻辑;这只是一个例子。

本质上,我们(逻辑上)在这里所做的是在两个进程之间共享一个布尔值。您必须小心设置和重置该共享布尔值的顺序。

于 2013-02-22T13:46:01.510 回答
0

试试FileSystemWatcher

侦听文件系统更改通知并在目录或目录中的文件更改时引发事件。

于 2013-02-22T13:16:27.507 回答