I have a class called DirectoryCopier
which expose progress event in which my windows form object will subscribe to this event then call CopyFolderAsync to start copying & notify event handlers on different thread.
class DirectoryCopier
{
public event EventHandler<CopyProgressChangedEventArgs> CopyProgressChanged;
public void CopyFolderAsync()
{
Task.Run(() => CopyFolder(Source, Destination));
}
void CopyFolder(string src, string des)
{
string srcName = Path.GetFileName(src);
string desDir = Path.Combine(des, srcName);
Directory.CreateDirectory(desDir);
var files = Directory.EnumerateFiles(src);
foreach (string file in files)
{
string fileName = Path.GetFileName(file);
string desFile = Path.Combine(desDir, fileName);
CopyFile(file, desFile);
}
var dirs = Directory.EnumerateDirectories(src);
foreach (string dir in dirs)
CopyFolder(dir, desDir);
}
void CopyFile(string src, string dest)
{
using (FileStream input = new FileStream(src, FileMode.Open, FileAccess.Read, FileShare.None, buffer.Length))
using (FileStream output = new FileStream(dest, FileMode.Create, FileAccess.Write, FileShare.None, buffer.Length))
{
byte[] buffer = new byte[1024 * 1024];
int bytesRead;
do
{
bytesRead = input.Read(buffer, 0, buffer.Length);
output.Write(buffer, 0, bytesRead);
if (CopyProgressChanged != null)
CopyProgressChanged.BeginInvoke(this, new CopyProgressChangedEventArgs(,,,),null,null);
}
while (bytesRead > 0);
}
}
}
In my form's event handler, i do update a progressbar with the received event args, this works fine when i run.
progressBar1.Value = e.ProgressPercentage;
When i debug my app the progressbar value is updated normally but is not advanced in my form and many cross-thread exceptions have been caught in IntelliTrace pane. I can use Form.Invoke() to update the progressBar but is this the responsibility of the event handler? is there any way to invoke every subcriber on his own/creation thread?