在我们的WCF服务中,客户端可以上传文件块。 几个客户端上传文件,一些客户端在多个线程上传。 为了序列化服务器端的文件访问,我们创建了一个字典来锁定给定的文件访问。 当一个线程想要访问一个文件进行写入时,检查这个字典是否包含给定的文件名。 如果包含-则表示线程当前正在访问该文件。 要释放锁,我们只需从字典中删除文件名。
公共类FileUploader{private static readonly Dictionary FileStreams=new Dictionary(StringComparer.InvariantCultureIgnoreCase);
public void SaveChunk(String storagePath, File file, Int64 currentPos, Byte[] chunk)
{
using (var writer = new BinaryWriter(OpenFileStream(storagePath)))
{
try
{
SaveChunk(writer, currentPos, chunk);
}
finally
{
writer.Close();
RemoveLock(storagePath);
}
}
}
private Stream OpenFileStream(String fullFileName)
{
Stream result = null;
lock (FileStreams)
{
while (FileStreams.ContainsKey(fullFileName))
{
Monitor.Wait(FileStreams);
}
result = System.IO.File.Open(fullFileName, FileMode.OpenOrCreate, FileAccess.Write);
FileStreams[fullFileName] = true;
}
return result;
}
private void RemoveLock(String fileName)
{
lock (FileStreams)
{
FileStreams.Remove(fileName);
Monitor.Pulse(FileStreams);
}
}
不知何故,我们spmetime得到了一条错误消息:
该进程无法访问文件“\ourstorage\folder\a_file_name.zip”,因为另一个进程正在使用该文件。
位于System.IO.__error.WinioError(Int32 errorCode,String maybeFullPath)
但我们看不出原因。 看起来代码是正确的,不会同时访问两个线程相同的文件。 知道吗?
在同一个文件中使用不同的线程进行编写。 你必须签入每个线程,如果你已经在写这个文件。