DelegateCommand异步等待与Task.Run UI锁定

问题描述 投票:1回答:1

我希望我的UI在单击按钮后显示加载叠加层。

选项1

MyCommand = new DelegateCommand(() => Task.Run(MyLongRunningTask);

private async Task MyLongRunningTask() {
    IsLoading = true;
    Thread.Sleep(5000);
    IsLoading = false;
}

选项2

MyCommand = new DelegateCommand(MyLongRunningMethod);

private async void MyLongRunningMethod() {
    IsLoading = true;
    Thread.Sleep(5000);
    IsLoading = false;
}

选项1有效,选项2无效。我很满意,尽管我不明白为什么。但我真的想避免必须将每个执行都包装到()=> Task.Run(...)。

由于异步void似乎不是一个好主意,我想继续使用任务。但是我想缩短语法,所以我想疯狂地尝试,但是我不知道如何将()=> Task.Run(..)放在派生于DelegateCommand的方法或类中。

为什么不编译?

    private DelegateCommand GetAsyncCommand(Task t)
    {
        return new DelegateCommand(() => Task.Run(t));
    }

与此类似的任何事情都会导致编译时错误,或者我必须调用

MyCommand = GetAsyncCommand(MyLongRunningTask());

由于()括号,它在实例化时立即执行我的任务。

这似乎让我很困惑。如果我必须将所有长时间运行的任务包装到此结构中,为什么我不能构建一个更智能的命令,该命令仅对给定任务对我有用?

编辑:我只是注意到选项1可能不会锁定UI,但是它吞噬了可怕的异常。

我如何设置不会阻塞UI并正常引发任何异常的命令?

c# wpf async-await command task
1个回答
2
投票

Thread.Sleep()正在锁定当前线程,而不管它在哪里:同步或异步方法。异步方法还有另一种暂停执行的方式-await Task.Delay()

asyncThreading不负责,async实现了一个state mashine,该代码执行代码以异步方式将其按等待的部分分割。 Task负责线程。

替换

Thread.Sleep(5000);

with

await Task.Delay(5000);

请注意,async void是不好的做法。 Look

© www.soinside.com 2019 - 2024. All rights reserved.