Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.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#_Asp.net_Task Parallel Library_Asp.net Web Api2 - Fatal编程技术网

C# 执行多个并发任务的最佳方法是什么?

C# 执行多个并发任务的最佳方法是什么?,c#,asp.net,task-parallel-library,asp.net-web-api2,C#,Asp.net,Task Parallel Library,Asp.net Web Api2,我一直在读异步编程的好处。这些好处似乎太大了,不能继续忽视它。因此,我决定坚定地进军异步、任务和等待的领域。我创建了一个简单的类来对我的Web Api执行多个并发POST操作 调用方法: ... int tasks = 100; for (var i = 0; i < tasks ; i++) { int taskNumber = i + 1; var task = Task.Run(() => Post(taskNumber , address, client

我一直在读异步编程的好处。这些好处似乎太大了,不能继续忽视它。因此,我决定坚定地进军异步、任务和等待的领域。我创建了一个简单的类来对我的Web Api执行多个并发POST操作

调用方法:

...

int tasks = 100;
for (var i = 0; i < tasks ; i++)
{
     int taskNumber = i + 1;
     var task = Task.Run(() => Post(taskNumber , address, client));
}

System.Console.ReadKey();
。。。
int任务=100;
对于(变量i=0;iPost(任务号、地址、客户端));
}
System.Console.ReadKey();
要运行的任务:

private static async Task Post(int taskNumber, Uri address, HttpClient client)
{
        System.Console.WriteLine("Started Task#: {0}", taskNumber);
        Stopwatch sw = new Stopwatch();
        sw.Start();
        var status = GetDeviceStatus();

        var response = await client.PostAsJsonAsync<DeviceStatus>(address, status);
        sw.Stop();

        if (response.IsSuccessStatusCode)
        {
            Uri statusUri = response.Headers.Location;
            System.Console.WriteLine("{0}- Elapsed: {1} Path: {2}", taskNumber, sw.Elapsed, statusUri.ToString());
        }
        else
        {
            System.Console.WriteLine("{0}- Elapsed: {1} Path: {2}", taskNumber, sw.Elapsed, response.ToString());                
        }
    }
private静态异步任务Post(int taskNumber、Uri地址、HttpClient客户端)
{
System.Console.WriteLine(“已启动的任务#::{0}”,任务编号);
秒表sw=新秒表();
sw.Start();
var status=GetDeviceStatus();
var response=wait client.PostAsJsonAsync(地址、状态);
sw.Stop();
if(响应。IsSuccessStatusCode)
{
Uri statusUri=response.Headers.Location;
System.Console.WriteLine(“{0}-appeased:{1}路径:{2}”,任务号,sw.appeased,statusUri.ToString());
}
其他的
{
System.Console.WriteLine(“{0}-appeased:{1}路径:{2}”,任务号,sw.appeased,response.ToString());
}
}

代码按预期工作;但是,这是执行此任务的最佳方式吗(请原谅双关语)?任何建议都将不胜感激。

我将采用Microsoft反应式框架来处理此类并行代码,而不是任务

下面是我要做的:

var query =
    from n in Observable.Range(0, 100)
    from r in Observable.Using(
        () => new HttpClient(),
        client =>
            Observable
                .Start(() =>
                {
                    var status = GetDeviceStatus();
                    return new
                    {
                        Response = client
                            .PostAsJson<DeviceStatus>(address, status),
                        Status = status,
                    };
                }))
    select new
    {
        Number = n,
        r.Response,
        r.Status,
    };
这一切都在线程池中处理。所有的同步都为您完成。我可以得到所有以匿名对象形式返回的结果

没有完美的方法可以做到这一点,但我喜欢这种方法。

我建议您使用基于I/O的并发和基于CPU的并发。因为WebAPI调用是I/O绑定的,所以应该使用TAP而不是TPL

无需调用
任务。在这种情况下运行

int requests = 100;
for (var i = 0; i < requests; i++)
{
  int taskNumber = i + 1;
  var task = PostAsync(taskNumber, address, client);
}

另外,
HttpClient
主要是线程安全的。详情见。

我认为使用task是处理此类问题的好方法。。我会说这是一个好办法。。但请记住比赛条件。。别忘了确保线程安全。。否则它是完美的,仅仅因为你把
threads=100
,并不意味着它使用100个线程。您所做的只是实例化100个
Task
对象。TPL如何决定创建线程和调度任务取决于TPL。将它们称为
tasks
而不是
threads
会更准确。代码中的一个问题是,所有100个任务都使用相同的
HttpClient
实例。
HttpClient
对象对于实例方法的调用不是线程安全的。您需要为每个调用创建一个新的客户端。注意不要混淆并行性和异步性。您可以通过异步运行这些操作来提升自己,但更重要的是,它们可以作为一组并行任务来调用。与for循环不同,Parallel.for更适合@Enigmativity-极好的观点。我已经在我的帖子中做了更正。
int requests = 100;
for (var i = 0; i < requests; i++)
{
  int taskNumber = i + 1;
  var task = PostAsync(taskNumber, address, client);
}
int requests = 100;
var tasks = Enumerable.Range(0, requests).Select(x => PostAsync(x + 1, address, client));
await Task.WhenAll(tasks);