简体   繁体   English

任务返回值,没有任务 <T> (异步/等待模式)

[英]Task return value, without Task<T> (async/await pattern)

I would like to write the following: 我想写下面的内容:

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!";
    });
}

As you can see to return the result from the DoSomeHeavyWork() I have used the Task.Result property, which works okay, but according to researches this will block the Thread. 正如你可以看到从DoSomeHeavyWork()返回结果我已经使用了Task.Result属性,这可以正常工作,但根据研究,这将阻止线程。

I would like to use the async/await pattern for this but cant seem to find how to do this. 我想使用async / await模式,但似乎无法找到如何做到这一点。 If I did the same with async/await with my current knowledge I will always end up with this: 如果我用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!";
    });
}

This solution doesnt quite fit my needs because I want to return ONLY the string and not a Task<string> , how can this be achieved with async/await? 这个解决方案不太适合我的需求,因为我想只返回字符串而不是Task<string> ,如何用async / await实现呢?

You can't. 你不能。

The entire point of async is to run code asynchronously . 整个点async异步运行的代码。 So the code returns a promise of a future string value, represented in .NET as Task<string> . 因此代码返回未来string值的承诺 ,在.NET中表示为Task<string>

Think about it this way: if your code calls public string GetSomeValue() , then by the time the method returns, you already have a string . 以这种方式思考:如果您的代码调用public string GetSomeValue() ,那么在方法返回时,您已经有了一个string This is synchronous, by definition. 根据定义,这是同步的。

In your example, you have "heavy" work which I interpret to mean "CPU-bound". 在你的例子中,你有“沉重”的工作,我解释为“CPU限制”。 In that case, just do the work synchronously: 在这种情况下,只需同步完成工作:

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

In general, APIs should not "lie"; 一般来说,API不应该“撒谎”; if they are synchronous, then they should have a synchronous (non- Task -returning) signature. 如果它们是同步的,那么它们应该具有同步(非Task返回)签名。

Edit: As per your comment, the "heavy" work is a WCF call, which is I/O-bound, not CPU-bound. 编辑:根据您的评论,“重”工作是一个WCF调用,它是I / O绑定的,而不是CPU绑定的。

In that case, the work is naturally asynchronous. 在这种情况下,工作自然是异步的。 Use asynchronous WCF methods (not Task.Run ), and allow the asynchrony to grow through your codebase: 使用异步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!";
}

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

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