Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何实现异步动作委托方法? 一点背景资料。_C#_Asynchronous_Asp.net Web Api_Async Await_C# 5.0 - Fatal编程技术网

C# 如何实现异步动作委托方法? 一点背景资料。

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() { 返回等

我正在学习WebAPI堆栈,并试图用Success和errorcode等参数以“Result”对象的形式封装所有数据

然而,不同的方法会产生不同的结果和错误代码,但是结果对象通常会以相同的方式实例化

为了节省一些时间,并进一步了解C#中的异步/等待功能,我试图将web api操作的所有方法体包装在异步操作委托中,但遇到了一点障碍

给定以下类别:
公共类结果
{
公共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;
}