We have a WinForm application that has a base form that all other forms inherit from.
On the base form there is a Delete button and the Delete button calls a virtual bool method called DeleteData.
public virtual void DeleteButton_Click(object sender, EventArgs e)
{
if (DeleteData())
{
// run some cleanup code
DoSomeCleanup();
}
}
public virtual bool DeleteData()
{
throw new NotImplementedException("Not implemented.");
}
Child form has overridden the DeleteData method
public override bool DeleteData()
{
try
{
// Delete some data
// Call async method that does some UI stuff and wait on it to finish
SomeSharedAsyncMethod();
return true;
}
catch(Exception ex)
{
// Handle exception
return false;
}
}
Here is the catch, SomeSharedAsyncMethod is mark as async and inside of it, it does some UI stuff like binding to textboxes and this method is called by others so the method must stay marked as "async"
public async Task SomeSharedAsyncMethod()
{
// Some code that has await and also some code that updates textboxes or other UI controls.
await Task.Delay(2000);
SomeTextBox.Text = "Some Text";
}
I can't add "async" to the "DeleteData" method because the base form is looking at the DeleteData method to run "DoSomeCleanup" and "DoSomeCleanup" would get called before DeleteData is finished.
Let's also assume that I can't add "async" to the delete button because I don't have control of that project.
I also don't want to override the DeleteButton_Click because I don't want to copy all the code that is located inside the base form DeleteButton_Click.
Here are some things I have tried:
public override bool DeleteData()
{
// Delete some data
// Call async method that does some UI stuff and wait on it to finish
// Causes a deadlock
SomeSharedAsyncMethod().Wait();
// RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.
SomeSharedAsyncMethod().RunSynchronously();
// This will not wait on SomeSharedAsyncMethod to execute
SomeSharedAsyncMethod().ConfigureAwait(false);
// Cross-thread operation not valid
Task.Run(async () => { await SomeSharedAsyncMethod(); }).Wait();
// This will not wait on SomeSharedAsyncMethod to execute
Task.Run(() => { SomeSharedAsyncMethod(); }).Wait();
// This will not wait on SomeSharedAsyncMethod to execute
Task.Run(async () => { await SomeSharedAsyncMethod().ConfigureAwait(false); }).Wait();
// This will not wait on SomeSharedAsyncMethod to execute
Task.Factory.StartNew(() =>
{
SomeSharedAsyncMethod().ConfigureAwait(false);
}, Task.Factory.CancellationToken, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()).Wait();
return true;
}
We are looking for a way of getting the DeleteData method to run all its code and not return until all lines of code has completed, this includes the SomeSharedAsyncMethod.