Task.FromResult在C#中有什么用
本文关键字:什么 FromResult TResult Task | 更新日期: 2023-09-27 18:36:40
在 C# 和 TPL(任务并行库)中,Task
类表示生成类型 T 类型的值的正在进行的工作。
我想知道 Task.FromResult 方法需要什么?
也就是说:在你手头已经有了产生的价值的情况下,有什么需要把它包装回一个任务中?
唯一想到的是,它被用作接受 Task 实例的其他方法的一些适配器。
我发现了两个常见的用例:
- 实现允许异步调用方的接口时,但实现是同步的。
- 当您存根/模拟异步代码进行测试时。
一个例子是使用缓存的方法。 如果结果已计算,则可以返回值为已完成的任务(使用 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);
}
}
}