Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.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_C# 5.0_Async Await - Fatal编程技术网

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在这里不合适吗?