c# - 为什么 await 永远不会返回?

标签 c# async-await task-parallel-library

我看到一个似乎永远不会返回的等待。这是示例代码:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private string _status;
    private CancellationTokenSource _cancellationTokenSource;

    public MainWindow()
    {
        InitializeComponent();

        _status = "Ready";

        DataContext = this;
    }

    public string Status
    {
        get { return _status; }
        set
        {
            _status = value;
            OnPropertyChanged(nameof(Status));
        }
    }

    private void OnStart(object sender, RoutedEventArgs e)
    {
        Status = "Running...";

        _cancellationTokenSource = new CancellationTokenSource();

        StartProcessing();
    }

    private void OnStop(object sender, RoutedEventArgs e)
    {
        _cancellationTokenSource.Cancel();
    }

    private async void StartProcessing()
    {
        try
        {
            await new Task(() =>
            {
                Thread.Sleep(5000);
            }, _cancellationTokenSource.Token);
        }
        catch (TaskCanceledException e)
        {
            Debug.WriteLine($"Expected: {e.Message}");
        }

        Status = "Done!";
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

调用 OnStart,将状态设置为“正在运行...”,然后调用 StartProcessing。五秒钟过去了,但是我从未看到状态设置为“完成!”

如果我调用 OnStop,任务就会取消,我会看到“完成!”状态。

我猜我正在创建一个任务以及由 async/await 创建的任务,但它挂起或死锁?

这是 WPF XAML 代码:

<Window x:Class="CancellationSample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Title="Cancellation Test" Height="350" Width="525">
<DockPanel LastChildFill="True">
    <StackPanel DockPanel.Dock="Top">
        <Button Width="70" Margin="5" Click="OnStart">Start</Button>
        <Button Width="70" Margin="5" Click="OnStop">Stop</Button>
    </StackPanel>
    <StatusBar DockPanel.Dock="Bottom">
        <StatusBarItem>
            <TextBlock Text="{Binding Status}"/>
        </StatusBarItem>
    </StatusBar>
    <Grid></Grid>
</DockPanel>
</Window>

最佳答案

您正在创建一个新任务 但并未启动它,因此它永远不会完成。而是使用 Task.Run然后 await

await Task.Run(() => { });

也考虑使用 Task.Delay而不是 Thread.Sleep 这样您就不会阻塞当前线程,

关于c# - 为什么 await 永远不会返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45458178/

相关文章:

c# - 即使使用 ConfigureAwait(false),HttpClient 的 PostAsync 方法也会阻塞

c# - 为什么不能从 Task 派生异步方法返回类型?

c# - MonoDevelop 2.4.1 未在 Windows 7 上运行最终无法加载 glibsharpglue-2

c# - 通用对象的通用列表

c# - 在 ASP.NET 4.6 中使用 Serilog 启动 OWIN

asynchronous - 如何将向量作为异步流处理?

c# - 从 Redis 检索多个键时死锁

c# - CancellationToken 阻塞线程执行

.net - 将现有异步方法包装成 TPL 兼容方法

c# - BindingContext 和多选数据 GridView