C# 我的方法真的是异步的吗?
我有这样的方法:C# 我的方法真的是异步的吗?,c#,asynchronous,c#-5.0,async-await,C#,Asynchronous,C# 5.0,Async Await,我有这样的方法: public async Task<IEnumerable<Model>> Get([FromUri]IList<string> links) { IList<Model> list = new List<Model>(); foreach (var link in links) { MyRequestAsync request = new MyRequestAsync(link
public async Task<IEnumerable<Model>> Get([FromUri]IList<string> links)
{
IList<Model> list = new List<Model>();
foreach (var link in links)
{
MyRequestAsync request = new MyRequestAsync(link);
list.Add(await request.GetResult());
}
return list;
}
但我只是想知道它是否真的是异步的,因为我认为part list.Addawait request.GetResult;和返回列表;破坏方法的异步性质
如果我错了,请纠正我,如果我是对的,我该如何解决
更新:根据我的理解,我必须返回等待任务。Run=>newlist{a,b};但不确定如何将其应用于我的案例。在我看来,I/O是异步的,因此可以将该方法称为真正的异步。
异步意味着I/O在等待结果时不会阻塞线程,但在列表中执行操作时不会阻塞线程。添加。在我看来,I/O是异步的,因此该方法可以称为真正的异步。
异步意味着当I/O在这里等待某个结果时,它不会阻塞线程,但当它在列表中执行某个操作时,它就不会阻塞线程。添加。这有点难说,因为你调用的任何东西都可能是阻塞操作。如果有一个阻塞操作隐藏在某处,这个方法也会阻塞。如果您想使一个方法无阻塞和/或只使用可伸缩异步IO,您必须检查您所做的和调用的一切
也就是说,您的代码看起来是非阻塞的,因为它使用Wait而不是Task.Wait。稍微简化一点,这个方法将返回第一个等待操作,这可能是您需要的。这有点难以判断,因为您调用的任何操作都可能是阻塞操作。如果有一个阻塞操作隐藏在某处,这个方法也会阻塞。如果您想使一个方法无阻塞和/或只使用可伸缩异步IO,您必须检查您所做的和调用的一切
也就是说,您的代码看起来是非阻塞的,因为它使用Wait而不是Task.Wait。稍微简化一下,此方法将返回第一个等待操作,这可能是您需要的。您的方法是异步的,但可能没有充分利用资源 方法要做的是进入foreach循环,创建MyRequestAsync对象,然后在等待点放弃其线程,直到结果可用为止。一旦结果可用,就会找到合适的线程,该方法将恢复运行。它会将结果添加到列表中,并返回到循环的顶部,然后一遍又一遍地重复整个过程
但请考虑这一点——如果这些请求是独立的,那么您可以并行地生成每个请求,然后在所有请求完成后只继续运行您的方法。这大概是:
public async Task<IEnumerable<Model>> Get([FromUri]IList<string> links)
{
IList<Task<Model>> list = new List<Task<Model>>();
foreach (var link in links)
{
MyRequestAsync request = new MyRequestAsync(link);
list.Add(request.GetResult());
}
return new List<Model>(await Task.WhenAll(list));
//Or just
//return await Task.WhenAll(list);
//Since we don't need to return a list
}
但这可能会降低可读性。您的方法是异步的,但可能没有充分利用资源 方法要做的是进入foreach循环,创建MyRequestAsync对象,然后在等待点放弃其线程,直到结果可用为止。一旦结果可用,就会找到合适的线程,该方法将恢复运行。它会将结果添加到列表中,并返回到循环的顶部,然后一遍又一遍地重复整个过程
但请考虑这一点——如果这些请求是独立的,那么您可以并行地生成每个请求,然后在所有请求完成后只继续运行您的方法。这大概是:
public async Task<IEnumerable<Model>> Get([FromUri]IList<string> links)
{
IList<Task<Model>> list = new List<Task<Model>>();
foreach (var link in links)
{
MyRequestAsync request = new MyRequestAsync(link);
list.Add(request.GetResult());
}
return new List<Model>(await Task.WhenAll(list));
//Or just
//return await Task.WhenAll(list);
//Since we don't need to return a list
}
但这可能会降低它的可读性。我认为您可能不理解异步的实际含义。Eric Lippert的这篇文章是我通常建议人们开始阅读以理解async并等待关键字的地方。我想你可能不理解async的真正含义。Eric Lippert的这篇文章是我通常建议人们开始阅读以理解async和Wait关键字的地方。代码只进行调试,但不进行调试时,我没有得到任何结果。我认为我得到了死锁,因为对于我的理解,返回列表;不等待,直到list.Addawait request.GetResult;完成它确实在等待。这就是等待的重点。它暂停方法,直到给定任务完成。使用调试器在运行时检查列表。找出未正确填写的原因。调试时未收到任何错误。在这里问了相关的问题,代码只是在调试中工作,而不是在调试中,我没有得到任何结果,我认为我得到了死锁,因为我理解返回列表;不等待,直到list.Addawait request.GetResult;完成它确实在等待。这就是等待的重点。它暂停方法,直到给定任务完成。使用调试器在运行时检查列表。找出未正确填写的原因。调试时未收到任何错误。此处询问了相关问题,您不需要创建列表来从Task.Whall返回IEnumerable,就像您在第二个代码示例中所做的一样。@PauloMorgado-这就是它在返回下面的注释代码中所说的。您有什么理由
rallel.Foreach在这里不合适?您不需要创建一个列表来从Task.Whall返回IEnumerable,就像您在第二个代码示例中所做的那样。@PauloMorgado-这就是它在返回下面的注释代码中所说的。有什么原因说明Parallel.Foreach在这里不合适吗?