How can I copy a file in C# without blocking a thread?
You can use asynchronous delegates
public class AsyncFileCopier
{
public delegate void FileCopyDelegate(string sourceFile, string destFile);
public static void AsynFileCopy(string sourceFile, string destFile)
{
FileCopyDelegate del = new FileCopyDelegate(FileCopy);
IAsyncResult result = del.BeginInvoke(sourceFile, destFile, CallBackAfterFileCopied, null);
}
public static void FileCopy(string sourceFile, string destFile)
{
// Code to copy the file
}
public static void CallBackAfterFileCopied(IAsyncResult result)
{
// Code to be run after file copy is done
}
}
You can call it as:
AsyncFileCopier.AsynFileCopy("abc.txt", "xyz.txt");
This link tells you the different techniques of asyn coding
You can do it as this article suggested:
public static void CopyStreamToStream(
Stream source, Stream destination,
Action<Stream, Stream, Exception> completed)
{
byte[] buffer = new byte[0x1000];
AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(null);
Action<Exception> done = e =>
{
if(completed != null) asyncOp.Post(delegate
{
completed(source, destination, e);
}, null);
};
AsyncCallback rc = null;
rc = readResult =>
{
try
{
int read = source.EndRead(readResult);
if(read > 0)
{
destination.BeginWrite(buffer, 0, read, writeResult =>
{
try
{
destination.EndWrite(writeResult);
source.BeginRead(
buffer, 0, buffer.Length, rc, null);
}
catch(Exception exc) { done(exc); }
}, null);
}
else done(null);
}
catch(Exception exc) { done(exc); }
};
source.BeginRead(buffer, 0, buffer.Length, rc, null);
I implemented this solution for copying large files (backup files) and it's terribly slow! For smaller files, it's not a problem, but for large files just use File.Copy or an implementation of robocopy with parameter /mt (multithread).
Note that this, copy file async, is still an open issue for .net development: https://github.com/dotnet/runtime/issues/20695
The correct way to copy: use a separate thread.
Here's how you might be doing it (synchronously):
//.. [code]
doFileCopy();
// .. [more code]
Here's how to do it asynchronously:
// .. [code]
new System.Threading.Thread(doFileCopy).Start();
// .. [more code]
This is a very naive way to do things. Done well, the solution would include some event/delegate method to report the status of the file copy, and notify important events like failure, completion etc.
cheers, jrh