是等待来自同步源的方法等待Task.Run(()=>良好做法?

时间:2018-02-17 08:41:34

标签: c# asp.net

我有一个带有任务的async关键字的方法。这个方法返回一个来自JwtSecurityTokenHandler().WriteToken(t);的字符串。事情是方法正文中的任何一个都没有等待。我得到警告CS-1998。这表示你不应该使用async来完成同步方法。但随后它补充说你可以使用await Task.Run(() => {。这样做是好的做法吗?

public async Task<object> GenerateMyUserJwtToken(string email, IdentityUser user)
//code that isnt awaitable
        {
var u = await Task.Run(() =>
            {
                return new JwtSecurityTokenHandler().WriteToken(token);
            });

            return  u;
}

编辑:我没有问我是什么错误,如果在没有等待分配的异步方法签名上实现await Task.Run(()是一个好主意。我还要求另一个异步方法正在等待这是另一种方法,这里是代码

//等待方法:

public async Task<object> LoginAsync(LoginDto model)
        {

                return await GenerateMyUserJwtToken(model.Email, appUser);

        }



//controller:
    [HttpPost("login")]
            public async Task<object> Login([FromBody] LoginDto model)
            {


      var logMeIn = await new AuthUserService().LoginAsync(model);
                return logMeIn; //returns token


            }

我的问题是这一直是异步还是任务。运行是否停止了这个过程?

1 个答案:

答案 0 :(得分:3)

仅使用Task.Run进行同步通常是一种不好的做法,但通常无法说明。

如果要执行的同步方法可能需要很长时间,那么可以解决方案。请注意,Task.Run会将任务分配给池线程,并不总是需要。常见的误解是异步方法总是使用或应该在async-await链的末尾某处使用线程。但是,async-await有nothing to do with threads,它是关于异步(链接延迟任务)和创建线程只是创建等待任务的一个选项。

那么有什么选择?

  1. 要调用的方法很快,并且永远不会长时间阻止调用方(> 100ms左右):根本不要使用异步。在这种情况下,Task<T>.FromResult(result)是一个诱人的解决方案,但非常气馁,因为它会给调用者带来误导。仅在单元测试中使用它,或者如果您被迫实现接口的异步方法,则无法更改。

  2. 方法执行需要很长时间,因为它是CPU绑定的:现在你可以使用一个线程。但我通常不会将池线程用于持久的任务,因为如果线程池没有线程,它可能会导致令人讨厌的副作用。请改用await Task.Factory.StartNew(() => MyLongRunningTask(), cancellationToken, TaskCreationOptions.LongRunning);,这会创建一个全新的线程,而不是打扰池。

  3. 方法执行需要很长时间,因为它是IO绑定的(例如,通过硬件发送/接收数据包):使用TaskCompletitionSource<T>,为设备的任何completition事件添加一个钩子(例如,OS挂钩或IRQ通知)并从中设置完成源的结果并返回其任务。