任务返回值,不带Task<(异步/等待模式)

本文关键字:异步 等待 模式 返回值 不带 Task 任务 | 更新日期: 2023-09-27 18:03:37

我想写以下内容:

public string GetSomeValue()
{
    //directly return the value of the Method 'DoSomeHeavyWork'...
    var t = DoSomeHeavyWork();
    return t.Result;
}
public Task<string> DoSomeHeavyWork()
{
    return Task.Run(() => {
        // do some long working progress and return a string
        return "Hello World!";
    });
}

正如您所看到的,为了从DoSomeHeavyWork()返回结果,我使用了Task。结果属性,它工作正常,但根据研究,这将阻塞线程。

我想使用async/await模式,但似乎无法找到如何做到这一点。如果我用我目前的知识对async/await做同样的事情,我将总是以这样结束:

public async Task<string> GetSomeValue()
{
    //directly return the value of the Method 'DoSomeHeavyWork'...
    var t = DoSomeHeavyWork();
    return await t;
}
public Task<string> DoSomeHeavyWork()
{
    return Task.Run(() => {
        // do some long working progress and return a string
        return "Hello World!";
    });
}

这个解决方案不太适合我的需要,因为我想只返回字符串,而不是一个Task<string>,这怎么能与async/await实现?

任务返回值,不带Task<(异步/等待模式)

你不能。

async的全部意义在于异步运行代码。因此,代码返回一个承诺未来的string值,在。net中表示为Task<string>

可以这样想:如果你的代码调用了public string GetSomeValue(),那么在方法返回的时候,你已经有了一个string。根据定义,这是同步的。

在你的例子中,你有"繁重"的工作,我解释为"cpu限制"。在这种情况下,只需同步执行工作:

public string DoSomeHeavyWork()
{
  // do some long working progress and return a string
  return "Hello World!";
}

一般来说,api不应该"说谎";如果它们是同步的,那么它们应该具有同步(非Task返回)签名。

编辑:根据您的评论,"繁重"的工作是一个WCF调用,这是I/o绑定,而不是cpu绑定。

在这种情况下,工作自然是异步的。使用异步WCF方法(而不是Task.Run),并允许异步在代码库中增长:
public async Task<string> GetSomeValueAsync()
{
  //directly return the value of the Method 'DoSomeHeavyWork'...
  var t = DoSomeHeavyWorkAsync();
  return await t;
}
public async Task<string> DoSomeHeavyWorkAsync()
{
  // Call asynchronous WCF client.
  await ...;
  return "Hello World!";
}