我应该将一个任务包装在另一个任务中还是应该只返回创建的任务? [英] Should I wrap a task in another task or should I just return the created task?

查看:93
本文介绍了我应该将一个任务包装在另一个任务中还是应该只返回创建的任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个使用ADO.NET的.NET 4.0应用程序,因此我无法使用async / await。
我不想要一个解决方案,但是我想知道以下哪种实现是最佳的,为什么。我的单元测试通过了所有三个实现,但是我想知道这三个实现之间的区别。

I'm building a .NET 4.0 application that uses ADO.NET, so I cannot use async/await. I don't want a solution for that, but I do want to know what of the following implementations is best and why. My unit tests pass for all three implementations, but I want to know the difference between these three.

在第一个实现中,我将一个任务包装在另一个任务中。我认为将两项任务分开对性能不利,但我不确定。

In my first implementation I wrap a task in another task. I think spinning up two tasks is bad for performance, but I'm not sure.

public virtual Task<IDataReader> ExecuteReaderAsync(IDbCommand dbCommand, CancellationToken cancellationToken)
{
    return Task.Factory.StartNew(() =>
    {
        var sqlCommand = CheckIfSqlCommand(dbCommand);
        PrepareExecuteReader(dbCommand);

        return Task<IDataReader>
            .Factory
            .FromAsync(sqlCommand.BeginExecuteReader, sqlCommand.EndExecuteReader, null)
            .Result;
    }, cancellationToken);
}



#2使用TaskCompletionSource



然后我尝试将结果包装在 TaskCompletionSource 中,这样我只有一个任务。

#2 Using TaskCompletionSource

Then I tried wrapping the result in a TaskCompletionSource so I just have one task.

public virtual Task<IDataReader> ExecuteReaderAsync(IDbCommand dbCommand, CancellationToken cancellationToken)
{
    var taskCompletionSource = new TaskCompletionSource<IDataReader>();
    var sqlCommand = CheckIfSqlCommand(dbCommand);
    PrepareExecuteReader(dbCommand);

    var reader = Task<IDataReader>
        .Factory
        .FromAsync(sqlCommand.BeginExecuteReader, sqlCommand.EndExecuteReader, null)
        .Result;

    taskCompletionSource.SetResult(reader);

    return taskCompletionSource.Task;
}



#3直接返回Task



我的最终解决方案是直接返回我创建的任务,而不是包装它。

#3 returning Task directly

My final solution is to directly return the task I created instead of wrapping it.

public virtual Task<IDataReader> ExecuteReaderAsync(IDbCommand dbCommand, CancellationToken cancellationToken)
{
    var sqlCommand = CheckIfSqlCommand(dbCommand);
    PrepareExecuteReader(dbCommand);

    return Task<IDataReader>
        .Factory
        .FromAsync(sqlCommand.BeginExecuteReader, sqlCommand.EndExecuteReader, null);
}



所以基本上我的问题是:



我应该使用什么选项,或者有更好的方法呢?

So basically my question is:

What option should I use or is there a better way to do this?

推荐答案

您的#3是最好。前两个无故引入了并发症。

Your #3 is the best. The first two introduce complication for no reason.

1可能纯粹添加另一个线程来运行 CheckIfSqlCommand() PrepareExecuteReader()异步。这可能就是您想要的,但是它们听起来并不像要花费很长时间的命令。

1 potentially adds another thread purely to run CheckIfSqlCommand() and PrepareExecuteReader() asynchronously. This may be what you wanted, but they don't sound like commands that are going to take a long time.

2个引用 .Result 的任务,该任务将一直阻塞到任务完成为止,因此无法实现使用任务的全部目的。

2 references .Result of the task, which will block until the task is complete, so defeats the whole purpose of using tasks.

这篇关于我应该将一个任务包装在另一个任务中还是应该只返回创建的任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆