I am reading source file in chunks and pass it to WCf service to write down on some remote SMB. I am keeping open the FileStream until all data is written.
Opening and closing file handle multiple time decrease performance so I am following this approach.
Once all data is written, I call CloseHandle(). Then I may need to perform some other operation on same file by calling DoSomeOperation(). As I have closed the file handle in CloseHandle() function, but I get the error "file is in use with some other process" in DoSomeOperation(). If I call DoSomeOperation() after some delay then issue is not there.
Please help us to close the file handle instantly as I call FileStream.Close().
This code snippet is part of a big program, so I can't mention all the code here.
//In WCF service
FileStream fs = null;
public void AppendBytes(string fileName, byte[] data, long position)
{
try
{
if (fs==null)//In first call, open the file handle
fs = System.IO.File.Open(fileName, System.IO.FileMode.Append, System.IO.FileAccess.Write, System.IO.FileShare.None);
fs.Write(data, 0, data.Length);
}
catch (Exception ex)
{
//Close handle in case of error
if (fs != null)
fs.Close();
}
}
public void CloseHandle()
{
//Close handle explicitly
if (fs != null)
fs.Close();
}
public void DoSomeOperation(string fileName)
{
using (FileStream fsO = System.IO.File.Open(fileName, System.IO.FileMode.Append, System.IO.FileAccess.Write, System.IO.FileShare.None))
{
//Do something with file here, this is atomic operation so I am opening FileStream with 'using' to dispose at operation is over
}
}
//In client
public void CallerFunction()
{
//Read Data from sourceFile in chunk and copy to target file using WCF.AppendBytes on another machine
WCF.AppendBytes(filename, data, pos);
WCF.CloseHandle();
WCF.DoSomeOperation(filename); //I get error here that file is in use with some other process. if I put a thread.sleep(1000) just before this statement then all works fine.
}
I have written a small test code to reproduce the same scenario on console application: Just Call TestHandleClose() from Main(), it will give error after some cycles.
static void TestHandleClose()
{
int i = 0;
try
{
if (File.Exists(@"d:\destination\file2.exe"))
File.Delete(@"d:\destination\file2.exe");
byte[] data = null;
int blocksize = 10 * 1024 * 1024;
for( i=0;i<100;i++)
{
using (FileStream fr = File.Open(@"d:\destination\File1.zip", FileMode.Open, FileAccess.Read, FileShare.None))
{
data = new byte[blocksize];
fr.Read(data, 0, blocksize); //We are reading the file single time but appending same data to target file multiple time.
using (FileStream f = File.Open(@"d:\destination\file2.exe", FileMode.Append, FileAccess.Write, FileShare.None))
{
f.Write(data, 0, data.Length); //We are writing same data multiple times.
f.Flush();
f.Close();
}
}
}
if (File.Exists(@"d:\destination\file2.exe"))
File.Delete(@"d:\destination\file2.exe");
}
catch (Exception ex)
{
throw;
}
}