Reputation: 4514
I have a Winforms exe and from a menu I launch a slow-running process as a Task. It should take about 30 seconds to get the data and then show a dialog. Usually it no longer returns. I catch exceptions and nothing appears in the log so I know it's run ok. The form just never appears, and no CPU time seems to be taking up. Yet I run it in the debugger and step through the code and it works fine. Occasionally it does seem to work on a faster PC. What is happening?
private async void inPlayRecordToolStripMenuItem_Click(object sender, EventArgs e)
{
if (!GetClient()) return;
{
await Task.Run(() =>
{
LaunchForm();
});
}
}
private async void LaunchForm()
{
try
{
{
var inPlayView = new InPlayView();
await inPlayView.GetData();
inPlayView.ShowDialog();
}
}
catch (Exception ex)
{
Logger.LogMessage(ex.ToString());
}
}
Upvotes: 1
Views: 1153
Reputation: 398
I have used async/await on one of my projects and I can't think of a reason to do a ShowDialog
in a task. Not sure if this will work but you may want to change your flow a little bit. This should make it more consistent and possibly easier to debug.
private async void inPlayRecordToolStripMenuItem_Click(object sender, EventArgs e) {
if (!GetClient()) {
return;
}
var playView = await LaunchForm();
if (playView != null) {
playView.ShowDialog();
}
}
private async Task<InPlayView> LaunchForm() {
try {
var inPlayView = new InPlayView();
await inPlayView.GetData();
return inPlayView;
} catch (Exception ex) {
// do cleanup of view if needed
Logger.LogMessage(ex.ToString());
return null;
}
}
Upvotes: 0
Reputation: 8325
Do this instead:
private async void inPlayRecordToolStripMenuItem_Click(object sender, EventArgs e)
{
if (!GetClient()) return;
await LaunchForm();
}
private async Task LaunchForm()
{
try
{
var inPlayView = new InPlayView();
await inPlayView.GetData();
inPlayView.ShowDialog();
}
catch (Exception ex)
{
Logger.LogMessage(ex.ToString());
}
}
You don't want Task.Run()
for an already async method, and as a general rule, async void
is okay for event handlers only, so not the LaunchForm()
method.
Also as a comment points out, Task.Run()
queues the task to the ThreadPool, so it will end up off the UI thread.
Upvotes: 1