I have a wpf app in which one of the functions is to copy files. It functions correctly but can sometimes freeze the UI, so I am trying to add async/await functions to it.
this is the code:
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string[] files = filePickedTextBox.Text.Split('\n');
await Task.Run(() =>
{
foreach (var file in files)
{
try
{
AddValueLoadingBar(20, true);
File.Copy(file, Path.Combine(dialog.SelectedPath, Path.GetFileName(file)));
newDirTextBox.Text = Path.Combine(dialog.SelectedPath, Path.GetFileName(file));
}
catch(Exception ex)
{
newDirTextBox.Text = ex.ToString();
}
finally
{
AddValueLoadingBar(100, true);
}
}
});
I have tried adding dispatcher.invoke in several locations but always get an error that it's asking for a request from a different thread, when it needs to talk to the textbox.
I've been at this for hours and have searched many stackoverflow threads and other documents online but I cant figure out how to implement this.
Also I know my progress bar implementation sucks..but I'm not worried about that at the moment since I cant get this to run without freezing in the first place.
Any help would be great.
Thx
Here is where you use the System.Windows.Threading.Dispatcher class.
You know that the dialog constructor will run on the main thread. So when the dialog is created, you record the main thread's dispatcher as a member variable.
Then, inside the Task thread, make sure you dispatch any update changes to the windows thread via this dispatcher.
using System.Windows;
class MyTestDialog
{
readonly Dispatcher _uiThreadDispatcher = Dispatcher.CurrentDispatcher;
public async Task DoSomethingInBackround()
{
await Task.Run(
() =>
{
//
// Do a bunch of stuff here
//
_uiThreadDispatcher.BeginInvoke(
new Action(
() => newDirTextBox.Text = "Some progress text";
)
);
//
// Do some more stuff
//
}
);
}
}