Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.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通过使用线程调用api在循环中调用api_C#_Multithreading - Fatal编程技术网

C# C通过使用线程调用api在循环中调用api

C# C通过使用线程调用api在循环中调用api,c#,multithreading,C#,Multithreading,我陷入了这个问题。我有一个API,我必须在一个循环中多次调用它。获取IList中所有迭代的API响应。我必须对IList执行一些操作。我在循环中调用我的API。假设有5次循环迭代。每次当一个点击转到API时,它都会等待它的响应,然后从另一个点击执行。我想把这些调用写在一个线程中。在末尾获取所有线程的响应。然后对该响应执行我的业务逻辑 我的伪代码是这样的 foreach (..... ) {

我陷入了这个问题。我有一个API,我必须在一个循环中多次调用它。获取IList中所有迭代的API响应。我必须对IList执行一些操作。我在循环中调用我的API。假设有5次循环迭代。每次当一个点击转到API时,它都会等待它的响应,然后从另一个点击执行。我想把这些调用写在一个线程中。在末尾获取所有线程的响应。然后对该响应执行我的业务逻辑

我的伪代码是这样的

                    foreach (..... )
                    {
                       //want to open thread here
                       mylist.Add(CalltoAPI(Params));
                    }
                //want to wait for all thread to be closed.
                   PerformBusinessLogic(mylist);

你走在正确的轨道上:

您可以创建任务列表并添加它们。然后你可以等他们

var mylist = new List<Task>;
foreach (..... )
{
    //want to open thread here
    mylist.Add(CalltoAPIAsync(Params)); <== this should be an async task method
}
await Task.WhenAll(myList);
然后您可以迭代完成任务

试试看

编辑:代码位完成符:

public async Task DoSomething()
    {
        var ids = Enumerable.Range(1, 5);
        var myList = new List<Task<string>>();
        foreach (var id in ids)
        {
            myList.Add(CallApiAsync(id.ToString()));
        }
        await Task.WhenAll(myList);

        foreach (var task in myList)
        {
            Console.WriteLine(task.Result);
        }
    }


    public Task<string> CallApi(string id)
    {
        return Task.Run(() => id);
    }

不确定任务。结果,在我的脑海中-但你得到了一个想法:

你在正确的轨道上:

您可以创建任务列表并添加它们。然后你可以等他们

var mylist = new List<Task>;
foreach (..... )
{
    //want to open thread here
    mylist.Add(CalltoAPIAsync(Params)); <== this should be an async task method
}
await Task.WhenAll(myList);
然后您可以迭代完成任务

试试看

编辑:代码位完成符:

public async Task DoSomething()
    {
        var ids = Enumerable.Range(1, 5);
        var myList = new List<Task<string>>();
        foreach (var id in ids)
        {
            myList.Add(CallApiAsync(id.ToString()));
        }
        await Task.WhenAll(myList);

        foreach (var task in myList)
        {
            Console.WriteLine(task.Result);
        }
    }


    public Task<string> CallApi(string id)
    {
        return Task.Run(() => id);
    }

不确定任务。结果,我想不出来-但你明白了:

在这里很难找到最佳答案,因为它在很大程度上取决于特定的细节,如调用方应用程序类型控制台、asp.net、winform等等。。。最大迭代次数,被调用API的性能

总之,并行多线程编程是一个棘手的问题,我建议对它进行更深入的研究

然而,鉴于所提供的信息量,我建议:

var myConcurentlist = new ConcurentBag<CallToApiReturnType>();
Parallel.ForEach(allApiCallsArgs, (oneApiCallArgs) => 
{
    myConcurentlist.Add(CalltoAPI(Params));
});
mylist = myConcurentlist.ToList();

请注意,您不应直接使用mylist,因为从多个线程同时使用List是不安全的,例如此处所述

很难在此处找到最佳答案,因为它在很大程度上取决于调用方应用程序类型控制台、asp.net、winform等特定细节。。。最大迭代次数,被调用API的性能

总之,并行多线程编程是一个棘手的问题,我建议对它进行更深入的研究

然而,鉴于所提供的信息量,我建议:

var myConcurentlist = new ConcurentBag<CallToApiReturnType>();
Parallel.ForEach(allApiCallsArgs, (oneApiCallArgs) => 
{
    myConcurentlist.Add(CalltoAPI(Params));
});
mylist = myConcurentlist.ToList();

请注意,您不能直接使用mylist,因为从多个线程同时使用List是不安全的,例如此处所述

这是一个太宽泛的问题。。。请进一步描述该api调用的行为,例如这是一个web调用,它的平均持续时间等。这正是微软的反应式框架设计的目的。您将得到这样一个查询:mylist中的from x.ToObservable from y in Observable.Start=>CalltoAPIx from z in Observable.Start=>PerformBusinessLogicx,y选择z。这都是多线程的。好的方面是,当您订阅查询时,您可以在生成值时返回值,而不是在最后。它非常干净。@Leonardo-为什么这个太宽了?如果有合适的签名等就好了,但对我来说这似乎是一个简单的场景。我已投票决定重新打开。@Enigmativity我没有投票决定关闭,但如果他告诉我API调用是winforms应用程序上的本地dll,而不是类似facebook的应用程序,我的答案会有很大变化。。。根据这方面的细节,我根本不推荐并行化!如果这是代码中大量使用的一部分呢?打开新线程可能会造成巨大的性能瓶颈,而不是加快速度…这是一个太宽泛的问题。。。请进一步描述该api调用的行为,例如这是一个web调用,它的平均持续时间等。这正是微软的反应式框架设计的目的。您将得到这样一个查询:mylist中的from x.ToObservable from y in Observable.Start=>CalltoAPIx from z in Observable.Start=>PerformBusinessLogicx,y选择z。这都是多线程的。好的方面是,当您订阅查询时,您可以在生成值时返回值,而不是在最后。它非常干净。@Leonardo-为什么这个太宽了?如果有合适的签名等就好了,但对我来说这似乎是一个简单的场景。我已投票决定重新打开。@Enigmativity我没有投票决定关闭,但如果他告诉我API调用是winforms应用程序上的本地dll,而不是类似facebook的应用程序,我的答案会有很大变化。。。根据这方面的细节,我根本不推荐并行化!如果这是代码中大量使用的一部分呢?打开新线程可能会造成巨大的性能瓶颈,而不是加快速度。。。