I have the following:
public async Task<bool> SearchForUpdatesAsync()
{
return await TaskEx.Run(() =>
{
if (!ConnectionChecker.IsConnectionAvailable())
return false;
// Check for SSL and ignore it
ServicePointManager.ServerCertificateValidationCallback += delegate { return (true); };
var configurations = UpdateConfiguration.Download(UpdateConfigurationFileUri, Proxy);
var result = new UpdateResult(configurations, CurrentVersion,
IncludeAlpha, IncludeBeta);
if (!result.UpdatesFound)
return false;
_updateConfigurations = result.NewestConfigurations;
double updatePackageSize = 0;
foreach (var updateConfiguration in _updateConfigurations)
{
var newPackageSize = GetUpdatePackageSize(updateConfiguration.UpdatePackageUri);
if (newPackageSize == null)
throw new SizeCalculationException(_lp.PackageSizeCalculationExceptionText);
updatePackageSize += newPackageSize.Value;
_packageOperations.Add(new UpdateVersion(updateConfiguration.LiteralVersion),
updateConfiguration.Operations);
}
TotalSize = updatePackageSize;
return true;
});
}
As you can see I'm using Microsoft.Bcl. Now in my other class I wrote this code in a normal void:
TaskEx.Run(async delegate
{
// ...
_updateAvailable = await _updateManager.SearchForUpdatesAsync();
MessageBox.Show("Test");
});
The problem I have is that it executes _updateAvailable = await _updateManager.SearchForUpdatesAsync();
and then it doesn't continue the thread, it just stops as if there is nothing after that call. Visual Studio also tells me this after a while: Thread ... exited with code 259
, so something seems to be still alive.
I debugged through it to search for any exceptions that could maybe be swallowed, but nothing, everything works fine and it executes the return-statement. And that is what I don't understand, I never see the MessageBox and/or no code beyond this line's being executed. After I talked to some friends, they confirmed that this shouldn't be. Did I make a horrible mistake when implementing async-await?
Thanks in advance, that's actually all I can say about that, I got no more information, I appreciate any tips and help as far as it's possible.
The main issue that you're having is that you're unnecessarily wrapping your method in TaskEx.Run()
and you are probably experiencing deadlock somewhere.
Your method signature is currently:
public async Task<bool> SearchForUpdatesAsync()
This means the following:
async
--> Doesn't actually do anything, but provides a "heads up" thatawait
might be called within this method and that this method can be used as a runnable Task.Task
--> This method returns a runnable task that can be run asynchronously on the threadpool<bool>
--> This method actually returns bool when awaited.
The await TaskEx.Run()
is unnecessarily since this says run this method and then don't return until after a value is available. This is most likely causing a synchronization problem. Removing this construct will make your method work properly, however you'll notice that now you have no reason to even include the async
operator or the Task<T>
portion since the method is actually synchronous anyway. Usually you're only going to use async
identifier on the method signature if you have methods that you are going to call await
on them.
Instead you have two options.
SearchForUpdates()
you can wrap this in a Task<bool>.Run()
to run it asynchronously (or the Bcl equivalent)BackgroundWorker
and just calling this method within it.Regarding using the async-await pattern I think that this is a great article to use to make sure you're following best practices: https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
The best practice is to have async all the way through your layers, and then call await or less desirably .Wait() / .Result at the final use site.
Also, try to keep your UI calls separate from the backend work, since you can run into synchronicity/thread-context issue.
public class WinFormsCode
{
private async Task WinsFormCodeBehindMethodAsync()
{
var updatesAvailable = await _updateManager.SearchForUpdatesAsync();
MessageBox.Show("Updates Available: " + updatesAvailable.ToString());
}
private void WinsFormCodeBehindMethodSync()
{
var updatesAvailable = _updateManager.SearchForUpdatesAsync().Result;
MessageBox.Show("Updates Available: " + updatesAvailable.ToString());
}
}
public class UpdateManager
{
public async Task<bool> SearchForUpdatesAsync()
{
return true;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With