了解Task与Task <T>作为返回类型

时间:2019-08-09 14:41:20

标签: c# asynchronous task

很抱歉,如果此问题已在某处解决,但在此主题上的资源数量是不堪重负的。

我编写了以下等待异步调用的方法

public async Task GetAllObjectsNames(string bucketName)
{
    if (string.IsNullOrEmpty(bucketName))
    {
        throw new ArgumentNullException(nameof(bucketName), "bucket name can't be null or empty string");
    }

    var request = new ListObjectsRequest
    {
        BucketName = bucketName
    };

    await  s_client.ListObjectsAsync(request);
}

致力于解决返回Task与返回Task<T>之间的区别

public async Task<IEnumerable<string>> GetAllObjectsNames(string bucketName)
{
    if (string.IsNullOrEmpty(bucketName))
    {
        throw new ArgumentNullException(nameof(bucketName), "bucket name can't be null or empty string");
    }

    var request = new ListObjectsRequest
    {
        BucketName = bucketName
    };

    var response = await s_client.ListObjectsAsync(request);

    return response.S3Objects.Select(o => o.Key);
}

有人可以鸣叫吗?

2 个答案:

答案 0 :(得分:8)

Task表示可能正在进行的操作,或者可能已被取消,出现故障或已完成的操作。完成的Task不包含任何结果,仅表示操作已完成。

Task<T>还表示可能正在进行的操作,或者可能已被取消,出现故障或已经完成的操作。但是,完成的Task<T>将包含该操作的结果,您可以随后读取该结果。

您可以写:

public async Task<IEnumerable<string>> GetAllObjectsNames(string bucketName)
// ...
var objects = await GetAllObjectsNames("Foo");
await GetAllObjectsNames("Foo"); // Throws away the result of the Task

但是你只能写:

public async Task GetAllObjectsNames(string bucketName)
// ...
await GetAllObjectsNames("Foo");

从此版本的Task返回的GetAllObjectsNames不能包含结果,因此您只能知道该操作何时完成-无法从中获取结果。

您可以使用Task作为UploadObject方法的返回值-您在这里关心上载操作何时完成,但是没有任何结果可供您读取。您可能会将Task<T>用于GetAllObjectsNames,因为该操作的目的是获取一些值供您使用。

从概念上讲,这与返回void(不返回结果)的方法或返回其他任何值的方法之间的区别相同。或ActionFunc<T>之间的区别。

答案 1 :(得分:1)

System.Threading.Tasks.Task<TResult>表示一个异步操作,该操作可以返回一个值(类型为TResult)。

(如果有帮助,这类似于System.Func<…, TResult>,基本上是一个返回值的动作)。

System.Threading.Tasks.Task代表异步操作(不返回值)。

(同样,这类似于System.Action<…>。)