我有一个用 C# 开发的 WinForm 应用程序,它在我的本地驱动器中查找文件,如果找不到,则创建它,否则在文件中添加一些文本,然后读取它。
如果我从同一台机器上的两个不同文件夹运行我的应用程序的两个实例,我该如何同步呢?
当第一个实例处理文件时,我希望另一个实例不要中断。请注意,由于两者都是同一个应用程序的实例,它们在同一个目标文件夹上工作以读写文件。
是否需要实施任何线程技术?
我有一个用 C# 开发的 WinForm 应用程序,它在我的本地驱动器中查找文件,如果找不到,则创建它,否则在文件中添加一些文本,然后读取它。
如果我从同一台机器上的两个不同文件夹运行我的应用程序的两个实例,我该如何同步呢?
当第一个实例处理文件时,我希望另一个实例不要中断。请注意,由于两者都是同一个应用程序的实例,它们在同一个目标文件夹上工作以读写文件。
是否需要实施任何线程技术?
不需要同步原语。您应该能够以独占方式打开该文件。这将防止任何其他应用程序弄乱它。例如:
try
{
using (var fs = new FileStream("foo", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
try
{
// do stuff with file.
}
catch (IOException ex)
{
// handle exceptions that occurred while working with file
}
}
}
catch (IOException openEx)
{
// unable to open file
}
指定FileShare.None
将阻止任何其他应用程序在您打开文件时访问它。
我认为最简单的解决方案是使用带有 try catch 的 StreamReader 和 StreamWriter。如果一个实例打开了文件,另一个实例将抛出异常
try
{
using (StreamWriter sw = new StreamWriter("my.txt", true))
{
sw.WriteLine(dir.Name);
}
}
catch
{
//maybe retry in 5 seconds
}
你可以使用一个命名的系统范围的互斥锁,但是问题是另一个进程可能正在使用该文件(例如,用户)。文件系统是您需要的所有同步。这样的事情应该做你:
static bool AddTextToFile( string someText , int maxAttempts )
{
if ( string.IsNullOrWhiteSpace(someText) ) throw new ArgumentOutOfRangeException( "someText" ) ;
if ( maxAttempts < 0 ) throw new ArgumentOutOfRangeException( "maxAttempts" ) ;
bool success = false ;
int attempts = 0 ;
while ( !success )
{
if ( maxAttempts > 0 && ++attempts > maxAttempts ) { break ; }
try
{
using ( Stream s = File.Open( @"c:\log\my-logfile.txt" , FileMode.Append , FileAccess.Write , FileShare.Read ) )
using ( StreamWriter sw = new StreamWriter(s,Encoding.UTF8) )
{
sw.WriteLine("The time is {0}. The text is {1}" , DateTime.Now , someText );
success = true ;
}
}
catch (IOException)
{
// the file is locked or some other file system problem occurred
// sleep for 1/4 second and retry
success = false ;
Thread.Sleep(250);
}
}
return success ;
}
您可能想查看mutex。它们允许您进行跨进程锁定。当一个程序上的一个互斥体打开时,另一个程序中的一个互斥体将等待。