C# 返回任务与返回等待的结果时出现异常
我的理解是,如果您有一个C# 返回任务与返回等待的结果时出现异常,c#,asynchronous,async-await,C#,Asynchronous,Async Await,我的理解是,如果您有一个async方法,其中唯一的wait是Task的最终返回,那么您可以删除async和wait关键字,只返回Task 例如: public async Task<object> Handle(object message) { var result = await Task.FromResult(message); return result; } async Task Main() { // outputs: Request v
async
方法,其中唯一的wait
是Task
的最终返回,那么您可以删除async
和wait
关键字,只返回Task
例如:
public async Task<object> Handle(object message)
{
var result = await Task.FromResult(message);
return result;
}
async Task Main()
{
// outputs: Request
var requestHandlerAwaitingResult = (Request) await new HandlerAwaitingResult().Handle(new Request());
Debug.WriteLine(requestHandlerAwaitingResult.Description);
// InvalidCastException: Unable to cast object of type 'System.Threading.Tasks.Task`1[System.Object]' to type 'Request'.
var requestHandlerReturnTask = (Request) await new HandlerReturningTask().Handle(new Request());
Debug.WriteLine(requestHandlerReturnTask.Description);
}
public class Request
{
public string Description = "Request";
}
public class HandlerAwaitingResult
{
public async Task<object> Handle(object message)
{
await Task.Delay(TimeSpan.FromSeconds(1));
var result = await Task.FromResult(message);
return result;
}
}
public class HandlerReturningTask
{
public async Task<object> Handle(object message)
{
await Task.Delay(TimeSpan.FromSeconds(1));
return Task.FromResult(message);
}
}
公共异步任务句柄(对象消息)
{
var result=等待任务。FromResult(消息);
返回结果;
}
变成
public Task<object> Handle(object message)
{
return Task.FromResult(message);
}
公共任务句柄(对象消息)
{
返回Task.FromResult(消息);
}
但是,当方法包含多个WAIT语句时,这似乎不起作用
例如:
public async Task<object> Handle(object message)
{
var result = await Task.FromResult(message);
return result;
}
async Task Main()
{
// outputs: Request
var requestHandlerAwaitingResult = (Request) await new HandlerAwaitingResult().Handle(new Request());
Debug.WriteLine(requestHandlerAwaitingResult.Description);
// InvalidCastException: Unable to cast object of type 'System.Threading.Tasks.Task`1[System.Object]' to type 'Request'.
var requestHandlerReturnTask = (Request) await new HandlerReturningTask().Handle(new Request());
Debug.WriteLine(requestHandlerReturnTask.Description);
}
public class Request
{
public string Description = "Request";
}
public class HandlerAwaitingResult
{
public async Task<object> Handle(object message)
{
await Task.Delay(TimeSpan.FromSeconds(1));
var result = await Task.FromResult(message);
return result;
}
}
public class HandlerReturningTask
{
public async Task<object> Handle(object message)
{
await Task.Delay(TimeSpan.FromSeconds(1));
return Task.FromResult(message);
}
}
async Task Main()
{
//产出:请求
var requestHandlerAitingResult=(请求)等待新的HandlerAitingResult().Handle(新请求());
Debug.WriteLine(requestHandlerAitingResult.Description);
//InvalidCastException:无法将类型为“System.Threading.Tasks.Task`1[System.object]”的对象强制转换为类型为“Request”。
var requestHandlerReturnTask=(请求)等待新的HandlerReturningTask().Handle(新请求());
Debug.WriteLine(requestHandlerReturnTask.Description);
}
公共类请求
{
公共字符串Description=“Request”;
}
公共类handleRaitingResult
{
公共异步任务句柄(对象消息)
{
等待任务延迟(时间跨度从秒(1));
var result=wait Task.FromResult(消息);
返回结果;
}
}
公共类HandlerReturningTask
{
公共异步任务句柄(对象消息)
{
等待任务延迟(时间跨度从秒(1));
返回Task.FromResult(消息);
}
}
有人能告诉我为什么这不起作用吗
从根本上讲,两者之间的区别是什么
public class HandlerReturningTask
{
public async Task<object> Handle(object message)
{
await Task.Delay(TimeSpan.FromSeconds(1));
return Task.FromResult(message);
}
}
公共类HandlerReturningTask
{
公共异步任务句柄(对象消息)
{
等待任务延迟(时间跨度从秒(1));
返回Task.FromResult(消息);
}
}
及
公共类HandlerReturningTask
{
公共异步任务句柄(对象消息)
{
等待任务延迟(时间跨度从秒(1));
返回等待任务。FromResult(消息);
}
}
及
公共类HandlerReturningTask
{
公共任务句柄(对象消息)
{
返回Task.FromResult(消息);
}
}
我仍然不确定我是否理解这个问题。但根据您的编辑:
基本上,[…return Task.FromResult(message);
…]和[…return wait Task.FromResult(message);
…]之间的区别是什么
理解等待
的作用很重要:它表示方法中的一个点,方法可以在该点返回,然后在“等待”(例如任务
)完成后,方法中的执行可以恢复
如果任务
是任务
,那么等待
做的另一件事是,在方法中恢复执行时,为任务
对象打开T
值,即获取其结果
属性值。将等待
表达式计算到该值
最后,对于async Task
方法,return
语句使方法返回的Task
对象(在第一个wait
表达式中)在return{value}
表达式中具有Result
值
因此,在您的示例中,返回Task.FromResult(message)
使任务.Result
属性具有任务类型的对象的值。稍后,await
表达式计算该对象的结果
属性值,您尝试将其强制转换为请求
类型的对象,这当然是非法的
使用返回等待任务.FromResult(消息)
导致首先计算wait
表达式(因此return
语句可以返回该表达式的结果),其效果是获取Task.result
属性值。然后,该值由return
语句返回,导致等待的任务。Result
值成为最初传递给方法的请求
对象。当然,当调用者中的wait
打开包装时,可以将其转换回类型Request
也就是说,通常直接返回值。将其包装在任务
对象中,然后使用等待
表达式立即将其展开是毫无意义的。编写返回消息在这种情况下,code>将得到完全相同的结果,但具有更可读性和更高效的代码。生成的状态机处理任何可等待的数据。不仅仅是任务
如果您只处理一个任务,则可以绕过计算机生成的状态机的开销。但是,在出现异常的情况下,堆栈跟踪将不是您所期望的
异步方法的返回类型将始终是您返回的任务。根据您对编译器为异步方法创建的状态机的理解,您能否首先解释一下为什么从您的角度来看它应该工作?我同意前面的评论,但不理解您的要求。您(应该)知道,async
方法的return
语句返回Task
中类型为T
的对象。在句柄返回任务中,T
是对象
。然后,此对象由wait
展开。因此,您返回一个任务
对象,并尝试将其强制转换为结果
。为什么要这样做?而不是返回Task.FromResult(message)
,为什么您不只是返回消息代码>?