在后台线程上运行"async"方法

 技术小菜鸟 发布于 2023-02-13 17:07

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

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

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

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

抛出的异常是:

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

无论如何,这是什么意思?如何在后台线程上运行异步方法,将结果发送回UI线程?

编辑

也尝试了Task.Wait,但等待永远不会结束:

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

        // ^ stuck here

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

Cory Nelson.. 39

要具体修复您的示例:

public void Activate()
{
    Task.Factory.StartNew(() =>
    {
        //executes in thread pool.
        return GetSomething(); // returns a Task.
    }) // returns a 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());
}

这可行,但它是老派.

现代的方式运行在后台线程的东西,派遣回UI线程使用Task.Run(),async以及await:

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

Task.Run将在线程池线程中启动一些东西.当你await做某事时,它会自动回到启动它的执行上下文中.在这种情况下,您的UI线程.

你通常不需要打电话Start().首选async方法,Task.RunTask.Factory.StartNew- 所有方法都自动启动任务.使用awaitContinueWith在父项完成时自动启动的Continuations .

1 个回答
  • 要具体修复您的示例:

    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());
    }
    

    这可行,但它是老派.

    现代的方式运行在后台线程的东西,派遣回UI线程使用Task.Run(),async以及await:

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

    Task.Run将在线程池线程中启动一些东西.当你await做某事时,它会自动回到启动它的执行上下文中.在这种情况下,您的UI线程.

    你通常不需要打电话Start().首选async方法,Task.RunTask.Factory.StartNew- 所有方法都自动启动任务.使用awaitContinueWith在父项完成时自动启动的Continuations .

    2023-02-13 17:11 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有