我有一个wcf服务,允许客户端下载一些文件。虽然每个客户端的请求都有一个新的服务实例,但如果两个客户端同时尝试下载同一个文件,则首先请求到达锁定文件,直到完成它为止。因此,其他客户端实际上正在等待第一个客户端完成,因为没有多个服务。必须有办法避免这种情况。
有没有人知道如何在服务器硬盘上没有多个文件的情况下避免这种情况?或者我做错了什么?
这是服务器端代码:
`public Stream DownloadFile(string path) { System.IO.FileInfo fileInfo = new System.IO.FileInfo(path);
// check if exists
if (!fileInfo.Exists) throw new FileNotFoundException();
// open stream
System.IO.FileStream stream = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read);
// return result
return stream;
}`
这是客户端代码:
public void Download(string serverPath, string path)
{
Stream stream;
try
{
if (System.IO.File.Exists(path)) System.IO.File.Delete(path);
serviceStreamed = new ServiceStreamedClient("NetTcpBinding_IServiceStreamed");
SimpleResult<long> res = serviceStreamed.ReturnFileSize(serverPath);
if (!res.Success)
{
throw new Exception("File not found: \n" + serverPath);
}
// get stream from server
stream = serviceStreamed.DownloadFile(serverPath);
// write server stream to disk
using (System.IO.FileStream writeStream = new System.IO.FileStream(path, System.IO.FileMode.CreateNew, System.IO.FileAccess.Write))
{
int chunkSize = 1 * 48 * 1024;
byte[] buffer = new byte[chunkSize];
OnTransferStart(new TransferStartArgs());
do
{
// read bytes from input stream
int bytesRead = stream.Read(buffer, 0, chunkSize);
if (bytesRead == 0) break;
// write bytes to output stream
writeStream.Write(buffer, 0, bytesRead);
// report progress from time to time
OnProgressChanged(new ProgressChangedArgs(writeStream.Position));
} while (true);
writeStream.Close();
stream.Dispose();
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (serviceStreamed.State == System.ServiceModel.CommunicationState.Opened)
{
serviceStreamed.Close();
}
OnTransferFinished(new TransferFinishedArgs());
}
}
答案 0 :(得分:0)
我同意Kjörling先生的意见,如果没有看到你正在做的事情,很难提供帮助。由于您只是从服务器下载文件,为什么要将其打开为R / W(导致锁定)。如果以只读方式打开它,则它不会锁定。如果我的建议缺乏,请不要修改,因为只有我对这个问题的解释没有很多信息。
答案 1 :(得分:0)
试试这个,它应该允许两个线程同时并独立地读取文件:
System.IO.FileStream stream = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);