当前位置: 首页 > 知识库问答 >
问题:

“await task.run();return;”和“返回task.run()”?

宁侯林
2023-03-14
async Task TestAsync() 
{
    await Task.Run(() => DoSomeWork());
}
Task TestAsync() 
{
    return Task.Run(() => DoSomeWork());
}
async Task TestAsync() 
{
    await Task.Delay(1000);
}
Task TestAsync() 
{
    return Task.Delay(1000);
}

后期更新:除了接受的答案之外,localCallContext的处理方式也有所不同:即使没有异步,也会还原CallContext.LogicalGetData。为什么?

共有1个答案

狄玉书
2023-03-14

一个主要的区别是异常传播。在异步任务方法中引发的异常存储在返回的任务对象中,并保持Hibernate状态,直到通过await tasktask.wait()task.resulttask.getawaiter().getresult()观察到该任务。即使从Async方法的同步部分抛出,它也是以这种方式传播的。

考虑以下代码,其中onetestasyncanothertestasync的行为完全不同:

static async Task OneTestAsync(int n)
{
    await Task.Delay(n);
}

static Task AnotherTestAsync(int n)
{
    return Task.Delay(n);
}

// call DoTestAsync with either OneTestAsync or AnotherTestAsync as whatTest
static void DoTestAsync(Func<int, Task> whatTest, int n)
{
    Task task = null;
    try
    {
        // start the task
        task = whatTest(n);

        // do some other stuff, 
        // while the task is pending
        Console.Write("Press enter to continue");
        Console.ReadLine();
        task.Wait();
    }
    catch (Exception ex)
    {
        Console.Write("Error: " + ex.Message);
    }
}

如果调用dotestasync(OneTestAsync,-2),它将产生以下输出:

Press enter to continue
Error: One or more errors occurred.await Task.Delay
Error: 2nd
Error: The value needs to be either -1 (signifying an infinite timeout), 0 or a positive integer.
Parameter name: millisecondsDelayError: 1st
// async
async Task<int> MethodAsync(int arg)
{
    if (arg < 0)
        throw new ArgumentException("arg");
    // ...
    return 42 + arg;
}

// non-async
Task<int> MethodAsync(int arg)
{
    var task = new Task<int>(() => 
    {
        if (arg < 0)
            throw new ArgumentException("arg");
        // ...
        return 42 + arg;
    });

    task.RunSynchronously(TaskScheduler.Default);
    return task;
}

但是请注意,在某些条件下(例如当它在堆栈中太深时),runsynchronusy仍然可以异步执行。

static async Task TestAsync()
{
    await Task.Delay(1000);
}

void Form_Load(object sender, EventArgs e)
{
    TestAsync().Wait(); // dead-lock here
}

将其更改为非异步版本,它就不会死锁:

Task TestAsync() 
{
    return Task.Delay(1000);
}

Stephen Cleary在他的博客中很好地解释了死锁的本质。

 类似资料:
  • 描述 (Description) Mixins与函数类似,mixin中定义的变量将作为其返回值。 例子 (Example) 以下示例演示了在LESS文件中使用mixin & return values - <html> <head> <link rel = "stylesheet" href = "style.css" type = "text/css" /> <ti

  • 到目前为止,我们创建的函数都只是对传入的数据进行了处理,处理完了就结束。但实际上,在某些场景中,我们还需函数将处理的结果反馈回来,就好像主管向下级员工下达命令,让其去打印文件,员工打印好文件后并没有完成任务,还需要将文件交给主管。 Python中,用 def 语句创建函数时,可以用 return 语句指定应该返回的值,该返回值可以是任意类型。需要注意的是,return 语句在同一函数中可以出现多次

  • 本文向大家介绍JavaScript返回空值return;的作用,包括了JavaScript返回空值return;的作用的使用技巧和注意事项,需要的朋友参考一下 要说明JavaSctipt返回空值return;的作用,我们先看看 return 的一些细节知识,如:onClick='return add_onclick()' 与 onClick='add_onclick()' 的区别。 JavaScr

  • 问题内容: 我已经能够验证结果是否为。但是,它不返回列表。为什么? 问题答案: 对列表进行适当排序,即不返回新列表。写吧

  • 我对使用泽西2.29有问题。这是一个简单的例子。我设法返回纯文本,但如果我尝试返回XML,我会得到500个错误。 我的步骤: AlienResource.java

  • 通过使用引用而不是指针,可以使C ++程序更易于阅读和维护。 C ++函数可以以与返回指针类似的方式返回引用。 当函数返回引用时,它返回一个指向其返回值的隐式指针。 这样,函数可以在赋值语句的左侧使用。 例如,考虑这个简单的程序 - #include <iostream> #include <ctime> using namespace std; double vals[] = {10.1, 12