Await停止执行线程并且永远不会继续

Dom*_* B. 6 c# asynchronous winforms async-await

我有以下内容:

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;
});
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我正在使用Microsoft.Bcl.现在在我的另一个类中,我在正常的void中编写了这段代码:

TaskEx.Run(async delegate
{
    // ...
    _updateAvailable = await _updateManager.SearchForUpdatesAsync();
     MessageBox.Show("Test");
});
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是它执行_updateAvailable = await _updateManager.SearchForUpdatesAsync();然后它不会继续线程,它只是停止,好像在该调用之后没有任何内容.Visual Studio也会在一段时间后告诉我:Thread ... exited with code 259所以看起来似乎还活着.

我通过它进行调试以搜索可能被吞下的任何异常,但没有,一切正常并且它执行return -statement.这就是我不明白的地方,我从未看到MessageBox和/或没有代码超出此行的执行.在我和一些朋友交谈后,他们确认不应该这样做.在实现async-await时我犯了一个可怕的错误吗?

在此先感谢,这实际上我只能说,我没有更多的信息,我尽可能地感谢任何提示和帮助.

JNY*_*ger 5

您遇到的主要问题是您不必要地将方法包装在内,TaskEx.Run()并且您可能在某处遇到了死锁.

您的方法签名目前是:

public async Task<bool> SearchForUpdatesAsync()
Run Code Online (Sandbox Code Playgroud)

这意味着以下内容:

async- >实际上没有做任何事情,但提供了await可能在此方法中调用的"抬头",并且此方法可用作可运行的任务.
Task- >此方法返回一个可在线程池上异步运行的可运行任务
<bool>- >此方法实际上在等待时返回bool.

await TaskEx.Run()是不必要的,因为这说运行此方法,然后在值可用之后才返回.这很可能导致同步问题.删除此构造将使您的方法正常工作,但是您会注意到现在您没有理由甚至包括async运算符或Task<T>部分,因为该方法实际上是同步的.通常,async如果您要调用方法签名,那么您将只在方法签名上使用标识符await.

相反,你有两个选择.

  1. 无论何时你想调用SearchForUpdates()你都可以将Task<bool>.Run()它包装在一个异步运行它(或Bcl等价物)
  2. 由于您使用的是WinForms,因此最好使用a BackgroundWorker并在其中调用此方法.

关于使用async-await模式,我认为这是一篇很好的文章,用于确保您遵循最佳实践:https://msdn.microsoft.com/en-us/magazine/jj991977.aspx