简体   繁体   English

我可以使用async / await模拟后台工作者吗?

[英]Can I use async / await to simulate a background worker?

I'm trying to avoid having to chain a bunch of BackgroundWorkers together. 我试图避免将一堆BackgroundWorkers链接在一起。 I'm doing something that requires me to wait for the UI to update before continuing execution. 我正在做一些事情,要求我等待UI更新后才能继续执行。 Obviously, I can't use Sleep, as this blocks the UI thread from updating and defeats the purpose. 显然,我不能使用Sleep,因为这会阻止UI线程更新并达到目的。 I found the code below which I thought was the answer, but it appears the task.Wait(); 我找到了下面我认为是答案的代码,但它似乎是task.Wait(); line is still blocking the UI thread. 行仍在阻止UI线程。

static void Main(string[] args)
{
    var task = Task.Run(() => DoSomething());
    task.Wait();
    // once the task completes, now do more
}

static void DoSomething()
{
    // something here that is looking for the UI to change
}

I also tried the following, which did the same thing: 我还尝试了以下操作,它们的作用相同:

static void Main(string[] args)
{
    var task = Task.Run(() => DoSomethingAsync());
    task.Wait();
    // once the task completes, now do more
}

private async Task DoSomethingAsync()
{
    // something here that is looking for the UI to change
}

Is it possible to do what I want, and if so, what am I doing wrong? 是否可以做我想做的事情,如果是,我做错了什么?

You need to await the task instead of blocking on it. 您需要await任务而不是阻塞任务。 You can do that inside an async method. 您可以在async方法中执行此操作。

Now, Main can't be async but an event handler can be (which I guess is where you actually use that code): 现在, Main不能是async但是事件处理程序可以是(我想这是您实际使用该代码的地方):

public async void EventHandler(object sender, EventArgs e)
{
    await Task.Run(() => DoSomething()); // wait asynchronously
    // continue on the UI thread
}

Note that it's async void which should only be used on event handlers. 请注意,它是async void ,仅应在事件处理程序上使用。 All other async methods should return a task. 所有其他async方法应返回任务。

Using Task.Run means your using a ThreadPool thread. 使用Task.Run意味着您使用ThreadPool线程。 To really wait asynchronously for the UI to "do something" you should use TaskCompletionSource . 要真正异步地等待UI“执行某些操作”,您应该使用TaskCompletionSource You create it and await it's Task property and you complete that task when the UI changed: 创建它并await它的Task属性,并在UI更改后完成该任务:

public async void EventHandler(object sender, EventArgs e)
{
    _tcs = new TaskCompletionSource<bool>();
    await _tcs.Task;
}

public void UIChanged(object sender, EventArgs e)
{
    _tcs.SetResult(false);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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