简体   繁体   中英

DelegateCommand async await vs Task.Run UI locking

I want my UI to display a loading overlay once i click on my button.

Option 1

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

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

Option 2

MyCommand = new DelegateCommand(MyLongRunningMethod);

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

Option 1 works, option 2 does not. I'm fine with that being the case, although i don't understand why. But i would really like to avoid having to wrap every execute into () => Task.Run(...).

Since async void seems to be a bad idea, i would like to keep using tasks. But i want to shorten the syntax, so im trying like mad but i cannot figure out how to put the () => Task.Run(..) in a method or class that derives from DelegateCommand.

Why doesnt this compile?

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

Anything similiar to this leads to either compile time errors or i me having to call

MyCommand = GetAsyncCommand(MyLongRunningTask());

Because of the () braces it instantly executes my task on instantiation.

This seems really convoluted to me. If i have to wrap all my long running tasks into this construct, why cant i build a smarter command that just does that for me given a task?

Edit: I just notices that Option 1 might not lock the UI, but it swallows exceptions which is horrible.

How do i set up a command that does not block the UI and throws any exceptions normally?

Thread.Sleep() is locking the current thread regardless where it is: in sync or async method. Async method has another way to pause the execution - await Task.Delay() .

async is not responsible on Threading , async implements a state mashine that executes your code asynchroniously splitting it by awaitable parts. Task is responsible on Threading.

replace

Thread.Sleep(5000);

with

await Task.Delay(5000);

Note that async void is bad practice. Look .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM