C# 如何实现异步动作委托方法? 一点背景资料。
我正在学习WebAPI堆栈,并试图用Success和errorcode等参数以“Result”对象的形式封装所有数据 然而,不同的方法会产生不同的结果和错误代码,但是结果对象通常会以相同的方式实例化 为了节省一些时间,并进一步了解C#中的异步/等待功能,我试图将web api操作的所有方法体包装在异步操作委托中,但遇到了一点障碍 给定以下类别:C# 如何实现异步动作委托方法? 一点背景资料。,c#,asynchronous,asp.net-web-api,async-await,c#-5.0,C#,Asynchronous,Asp.net Web Api,Async Await,C# 5.0,我正在学习WebAPI堆栈,并试图用Success和errorcode等参数以“Result”对象的形式封装所有数据 然而,不同的方法会产生不同的结果和错误代码,但是结果对象通常会以相同的方式实例化 为了节省一些时间,并进一步了解C#中的异步/等待功能,我试图将web api操作的所有方法体包装在异步操作委托中,但遇到了一点障碍 给定以下类别: 公共类结果 { 公共bool成功{get;set;} 公共列表错误代码{get;set;} } 公共异步任务GetResultAsync() { 返回等
公共类结果
{
公共bool成功{get;set;}
公共列表错误代码{get;set;}
}
公共异步任务GetResultAsync()
{
返回等待DoSomethingAsync(结果=>
{
//在这里做点什么
结果:成功=正确;
如果(某件事)
{
结果.错误代码.添加(404);
结果:成功=错误;
}
}
}
我想写一个方法,在结果对象上执行一个操作并返回它
public T DoSomethingAsync<T>(Action<T> resultBody) where T : Result, new()
{
T result = new T();
resultBody(result);
return result;
}
public T DoSomethingAsync(Action resultBody),其中T:Result,new()
{
T结果=新的T();
结果体(result);
返回结果;
}
但是如何使用async/await将此方法转换为异步方法呢
这就是我尝试过的:
public async Task<T> DoSomethingAsync<T>(Action<T, Task> resultBody)
where T: Result, new()
{
// But I don't know what do do from here.
// What do I await?
}
公共异步任务DoSomethingAsync(操作结果体)
其中T:Result,new()
{
//但我不知道从这里该怎么办。
//我在等什么?
}
因此我认为实现这一点的方法是:
public Task DoSomethingAsync(Action resultBody),其中T:Result,new()
{
返回Task.Factory.StartNew(()=>
{
T结果=新的T();
结果体(result);
返回结果;
});
}
与操作
相当的异步
是Func
,因此我相信这就是您要寻找的:
public async Task<T> DoSomethingAsync<T>(Func<T, Task> resultBody)
where T : Result, new()
{
T result = new T();
await resultBody(result);
return result;
}
public异步任务DoSomethingAsync(Func resultBody)
其中T:Result,new()
{
T结果=新的T();
等待结果体(result);
返回结果;
}
如果你是新的
-升级T
,为什么你的方法需要是异步的?在使用异步API的代码中,你只需要从你使用的其他方法中传播异步的
特性。很抱歉,我对这一点还是相当陌生的,你说你只需要传播是什么意思,而升级T是什么意思与此有关吗?我想我已经弄明白了,谢谢millimoose你给了我一些思考的东西。你为什么还要尝试异步呢?在非Web服务器的情况下,通过在任务中包装同步代码(就像你正在尝试做的那样)来做伪异步比仅仅同步做慢。@AlbinAnke by“propagate”我的意思是,如果你在一个方法中调用一个.NET方法,比如Stream.ReadAsync()
,那么这个方法本身应该是异步的,并且返回一个Task
,其中T
是如果该方法是同步的,你应该返回的。这样的想法是,方法的每个调用者都可以“异步等待”(我不知道这是一个什么好术语)来完成底层的Stream.ReadAsync()
。你可以用一个比喻来比喻异步是“传染性的”,它从低级内置I/O传播到其他代码,其结果取决于所说的I/O。你应该避免任务。运行(更重要的是StartNew
)在ASP.NET上。有什么更好的方法可以做到这一点?我发布了一个答案,并对@svick的答案进行了投票。这两个答案都很好。@Stephen显然我正试图在MVVM ligth Messenger中实现一些类似的功能,我可以用同样的方法实现吗?@JuanPabloGomez:我不熟悉他们的消息类型,但我不明白为什么它不起作用。这太令人惊讶了ing!我认为不可能进行异步操作,并且已经认为这是一个语言缺陷。我没有考虑使用Func。谢谢。@DFSFOT:void
方法的异步等价物是一个任务
返回方法;因此,操作
的异步等价物是Func
,而Action
是Func
。详细信息。@DFSFOT:异步方法在没有返回值时应返回Task
。如果它使用async
关键字,则实际的Task
实例将由状态机创建,而不是由函数直接创建。
public Task<T> DoSomethingAsync<T>(Action<T> resultBody) where T : Result, new()
{
return Task<T>.Factory.StartNew(() =>
{
T result = new T();
resultBody(result);
return result;
});
}
public async Task<T> DoSomethingAsync<T>(Func<T, Task> resultBody)
where T : Result, new()
{
T result = new T();
await resultBody(result);
return result;
}