我在从正常的异步 ApiController 返回“立即”响应时遇到了问题。代码如下,查找感叹号。用例是内容类型检查失败,我想发回错误响应消息。第一个版本挂了 Visual Studion 2010(和 Fiddler)。第二个有效。
我的问题是,为什么我不能使用最初的方法来返回仅传回响应对象的虚拟任务?
public class MyController : ApiController
{
public Task<HttpResponseMessage> Post([FromUri]string arg)
{
HttpResponseMessage response = null;
// synchronous validation
if (Request.Content.Headers.ContentType.MediaType != @"image/jpeg")
{
response = Request.CreateErrorResponse(
HttpStatusCode.UnsupportedMediaType,
"Invalid Content-Type.");
}
if (response == null) // no immediate response, switch to async
{
// work done here
}
else // immediate response, but we need to wrap in a task for caller to fetch
{
// !!!! this one doesn't work !!!
return new Task<HttpResponseMessage>( () => response);
// !!! this one does !!!
TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompletionSource<HttpResponseMessage>();
tcs.SetResult(response);
return tcs.Task;
}
}
}
最佳答案
Task<T>
的构造函数返回一个尚未开始的任务,要让它工作,你必须做类似的事情:
var task = new Task<HttpResponseMessage>(() => response);
task.Start();
return task;
但这样做效率很低,因为 lambda 会在线程池上执行不必要的操作。您的第二个版本更好,在 .Net 4.5 中,更好的版本是使用 Task.FromResult()
:
return Task.FromResult(response);
关于c# - 从异步 ApiController 返回即时响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13039630/