运行“异步"后台线程上的方法 [英] Run "async" method on a background thread

查看:75
本文介绍了运行“异步"后台线程上的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从普通方法运行异步"方法:

I'm trying to run an "async" method from an ordinary method:

public string Prop
{
    get { return _prop; }
    set
    {
        _prop = value;
        RaisePropertyChanged();
    }
}

private async Task<string> GetSomething()
{
    return await new Task<string>( () => {
        Thread.Sleep(2000);
        return "hello world";
    });
}

public void Activate()
{
    GetSomething.ContinueWith(task => Prop = task.Result).Start();
    // ^ exception here
}

抛出的异常是:

可能不会在继续任务上调用开始.

Start may not be called on a continuation task.

那到底是什么意思?如何简单地在后台线程上运行异步方法,然后将结果分配回UI线程?

What does that mean, anyway? How can I simply run my async method on a background thread, dispatch the result back to the UI thread?

修改

还尝试了 Task.Wait ,但等待一直没有结束:

Also tried Task.Wait, but the waiting never ends:

public void Activate()
{
    Task.Factory.StartNew<string>( () => {
        var task = GetSomething();
        task.Wait();

        // ^ stuck here

        return task.Result;
    }).ContinueWith(task => {
        Prop = task.Result;
    }, TaskScheduler.FromCurrentSynchronizationContext());
    GetSomething.ContinueWith(task => Prop = task.Result).Start();
}

推荐答案

要具体解决您的示例,

public void Activate()
{
    Task.Factory.StartNew(() =>
    {
        //executes in thread pool.
        return GetSomething(); // returns a Task.
    }) // returns a Task<Task>.
    .Unwrap() // "unwraps" the outer task, returning a proxy
              // for the inner one returned by GetSomething().
    .ContinueWith(task =>
    {
        // executes in UI thread.
        Prop = task.Result;
    }, TaskScheduler.FromCurrentSynchronizationContext());
}

这行得通,但是已经过时了.

This will work, but it's old-school.

在后台线程上运行某些东西并分派回UI线程的现代方法是使用 Task.Run() async await :

The modern way to run something on a background thread and dispatch back to UI thread is to use Task.Run(), async, and await:

async void Activate()
{
    Prop = await Task.Run(() => GetSomething());
}

Task.Run 将在线程池线程中启动某些内容.当您 await 时,它会自动返回到启动它的执行上下文中.在这种情况下,您的UI线程.

Task.Run will start something in a thread pool thread. When you await something, it automatically comes back in on the execution context which started it. In this case, your UI thread.

通常,您永远不需要调用 Start().首选 async 方法, Task.Run Task.Factory.StartNew -所有这些方法都会自动启动任务.当父项完成时,使用 await ContinueWith 创建的继续也会自动开始.

You should generally never need to call Start(). Prefer async methods, Task.Run, and Task.Factory.StartNew -- all of which start the tasks automatically. Continuations created with await or ContinueWith are also started automatically when their parent completes.

这篇关于运行“异步"后台线程上的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆