Task.FromResult在C#中有什么用

本文关键字:什么 FromResult TResult Task | 更新日期: 2023-09-27 18:36:40

在 C# 和 TPL(任务并行库)中,Task 类表示生成类型 T 类型的值的正在进行的工作。

我想知道 Task.FromResult 方法需要什么?

也就是说:在你手头已经有了产生的价值的情况下,有什么需要把它包装回一个任务中?

唯一想到的是,它被用作接受 Task 实例的其他方法的一些适配器。

Task.FromResult<TResult>在C#中有什么用

我发现了两个常见的用例:

  1. 实现允许异步调用方的接口时,但实现是同步的。
  2. 当您存根/模拟异步代码进行测试时。

一个例子是使用缓存的方法。 如果结果已计算,则可以返回值为已完成的任务(使用 Task.FromResult )。 如果不是,则继续返回表示正在进行的工作的任务。

缓存示例:对预先计算的值使用 Task.FromResult 缓存示例

当您想要在不使用 async 关键字的情况下创建可等待的方法时,请使用它。我找到了这个例子:

public class TextResult : IHttpActionResult
{
    string _value;
    HttpRequestMessage _request;
    public TextResult(string value, HttpRequestMessage request)
    {
        _value = value;
        _request = request;
    }
    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage()
        {
            Content = new StringContent(_value),
            RequestMessage = _request
        };
        return Task.FromResult(response);
    }
}

在这里,您将创建自己的 IHttpActionResult 接口实现,以便在 Web API 操作中使用。ExecuteAsync 方法应该是异步的,但您不必使用 async 关键字来使其异步且可等待。 由于您已经有了结果并且不需要等待任何内容,因此最好使用 Task.FromResult。

从 msft.com 使用 Task.FromResult 创建预先计算的任务:

当您执行返回 Task 对象的异步操作并且已计算该 Task 对象的结果时,此方法很有用。

当您想要进行异步操作但有时结果是同步的时,请使用 Task.FromResult。你可以在这里找到一个很好的样本 http://msdn.microsoft.com/en-us/library/hh228607.aspx。

我认为您可以将 Task.FromResult 用于同步方法,这些方法需要很长时间才能完成,而您可以在代码中执行其他独立工作。不过,Id 宁愿让这些方法调用异步。但是想象一下这样的情况:您无法控制调用的代码,并且想要隐式并行处理。

Task.Run() 创建一个 lambda 线程,不需要异步并返回一个类型对象。在我的示例中,我有多个任务同时运行,等待它们完成。 完成所有任务后,我可以循环浏览它们的结果。 Task.FromResult 用于推送不是由 Task.Run() 生成的任务结果

在本例中,Task.FromResult 在 Result 类中推送一个类型对象 RecordStruct 类。 我创建了调用函数getData的任务。 Task.WaitAll 处理每个任务,并将结果推送到 RecordStruct 类型的结果对象数组中。 然后,我访问 RecordStruct 类的属性元素作为结果

    public class RecordStruct
    {
        public RecordStruct(string _element) {
            element = _element;
        }
        public string element { get;set; }
    }
public class TaskCustom
    {
        public Task<RecordStruct> getData(string phrase)
        {
            if (phrase == "hello boise")
            {
                return Task.FromResult(new RecordStruct("Boise is a great place to live"));
            }
            return Task.Run(() =>
            {
                return new RecordStruct(phrase);
            });
        }
    } 
[Fact]
        public async Task TestFactory()
        {
            TaskCustom obj = new TaskCustom();
            List<Task<RecordStruct>> tasks = new List<Task<RecordStruct>>();
            tasks.Add(obj.getData("hello world"));
            tasks.Add(obj.getData("hello boise"));
            Task.WaitAll(tasks.ToArray());
            for(int ctr = 0; ctr < tasks.Count; ctr++) {
                if (tasks[ctr].Status == TaskStatus.Faulted)
                    output.WriteLine(" Task fault occurred");
                else
                {
                    output.WriteLine("test sent {0}",
                                      tasks[ctr].Result.element);
                    Assert.True(true);
                }
            }
        }