Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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#_Multithreading_Asynchronous - Fatal编程技术网

C# 如何在指定的线程中运行异步方法

C# 如何在指定的线程中运行异步方法,c#,multithreading,asynchronous,C#,Multithreading,Asynchronous,我有一个应用程序(http web负载测试应用程序)需要new Thread(),而HttpClient只有异步方法,那么如何运行同步操作呢 ps:我尝试使用完整的任务,但它使用的线程数很低(仅30个线程), 所以我想试试线程,看看它是否能更快。 .GetAwaiter().GetResult()会花费2个线程(100个线程变成200个线程)吗 我以前用的 for(var i = 0; i< 200;i++) { Task.Run(async ()=> {

我有一个应用程序(http web负载测试应用程序)需要
new Thread()
,而
HttpClient
只有异步方法,那么如何运行同步操作呢

ps:我尝试使用完整的
任务
,但它使用的线程数很低(仅30个线程), 所以我想试试
线程
,看看它是否能更快。
.GetAwaiter().GetResult()
会花费2个线程(100个线程变成200个线程)吗


我以前用的

for(var i = 0; i< 200;i++)
{
    Task.Run(async ()=>
    {
        while(thereStillHaveRequestToMake)
        {
        await httpclient.SendAsync() // some thing like this
        }
    });
}

// the prolem is there are only 30-40 Thread in use (From TaskManager)

for(变量i=0;i<200;i++)
{
Task.Run(异步()=>
{
而(仍然有请求要做)
{
等待httpclient.SendAsync()//类似的内容
}
});
}
//问题是只有30-40个线程在使用(来自TaskManager)
所以我想切换到直接使用线程

for(var i = 0; i< 200;i++)
{
    new Thread(()=>
    {
        while(thereStillHaveRequestToMake)
        {
            httpclient.SendAsync().GetAwaiter.GetResult()
        }
    });
}
for(变量i=0;i<200;i++)
{
新线程(()=>
{
而(仍然有请求要做)
{
httpclient.SendAsync().GetAwaiter.GetResult()
}
});
}
我有一个需要新线程()的应用程序(http web负载测试应用程序)

为什么?

HttpClient只有异步方法,那么如何同步运行该操作呢

为什么

或者

我尝试使用完整任务,但它使用的线程数很低(仅30个线程)

任务不是线程。我们可以通过在线程池上运行方法轻松地测试这一点。首先,我们将线程池设置为只允许单个线程

class Program
{
  private const int MaxThreads = 1;

  static void Main(string[] args)
  {
    ThreadPool.SetMinThreads(MaxThreads, 1);
    Console.WriteLine(ThreadPool.SetMaxThreads(MaxThreads, 1));
    Task.Run(() => SomeMethod(new StateInfo { Order = 0, WaitFor = 3000 }));
    Task.Run(() => SomeMethod(new StateInfo { Order = 1, WaitFor = 3000 }));
    Task.Run(() => SomeMethod(new StateInfo { Order = 2, WaitFor = 3000 }));
    Console.WriteLine("Main thread does some work, then sleeps.");
    Thread.Sleep(5000);
    Console.WriteLine("Main thread exits.");
  }

  static void SomeMethod(Object stateInfo)
  {
    var si = (StateInfo)stateInfo;
    Console.WriteLine($"Hello from the thread pool. {si.Order}");
    Thread.Sleep(si.WaitFor);
  }

  public class StateInfo
  {
    public int Order { get; set; }
    public int WaitFor { get; set; }
  }
}
输出

真的

主线程做一些工作,然后休眠

线程池中的你好。一,

线程池中的你好。二,

主线程退出

因为我们有一个线程,我们已经告诉前两个方法总共等待6秒,但是主线程在5秒后退出,所以我们从来没有收到来自第三个方法的消息。我们可以通过更改
MaxThreads=2
来轻松测试这一点,这会产生如下结果(我们得到3个结果,但不一定按顺序):

真的

主线程做一些工作,然后休眠

线程池中的你好。一,

线程池中的你好。二,

线程池中的你好。三,

主线程退出

既然我们已经保证使用单个线程,那么让我们看看我们可以同时同步执行多少个请求

因为我们不是异步/等待请求,所以它是同步运行的,因此输出是可预测的:

真的

主线程做一些工作,然后休眠

线程池中的你好。一,

线程池中的你好。1完成

线程池中的你好。二,

线程池中的你好。2完成

线程池中的你好。三,

线程池中的你好。3完成

主线程退出

这并不是真正的负载测试,因为同步调用要等到前一个调用完成。为了进行负载测试,我们需要许多并发调用。这很容易通过使用async await的单个线程完成

更新方法:

static async Task SomeMethod(Object stateInfo)
{
  var si = (StateInfo)stateInfo;
  Console.WriteLine($"Hello from the thread pool. {si.Order}");
  await httpClient.GetStringAsync($"https://www.google.com");
  Console.WriteLine($"Hello from the thread pool. {si.Order} finished");
}
使用linq创建请求列表,并等待所有请求完成

static void Main(string[] args)
{
  ThreadPool.SetMinThreads(MaxThreads, 1);
  Console.WriteLine(ThreadPool.SetMaxThreads(MaxThreads, 1));

  Console.WriteLine("Start Requests");
  var requests = Enumerable.Range(0, 200)
    .Select(async (x) => await Task.Run(() => SomeMethod2(new StateInfo { Order = x, WaitFor = 0 })))
    .ToArray();

  Console.WriteLine("Wait for them.");
  Task.WaitAll(requests.ToArray());

  Console.WriteLine("Main thread exits.");
  Console.ReadKey();
}
收益率(我不想在这里放400行代码)

真的

启动请求

等等他们

线程池中的你好。0

线程池中的你好。一,

线程池中的你好。二,

。。。。重复

线程池中的你好。199

线程池中的你好。178完成

线程池中的你好。5完成

线程池中的你好。3完成

线程池中的你好。15完成

线程池中的你好。26完成

线程池中的你好。4完成

。。。。重复,直到完成所有200个请求

主线程退出

单个线程上有200个Http请求。为什么需要更多的线程

我有一个需要新线程()的应用程序(http web负载测试应用程序)

为什么?

HttpClient只有异步方法,那么如何同步运行该操作呢

为什么

或者

我尝试使用完整任务,但它使用的线程数很低(仅30个线程)

任务不是线程。我们可以通过在线程池上运行方法轻松地测试这一点。首先,我们将线程池设置为只允许单个线程

class Program
{
  private const int MaxThreads = 1;

  static void Main(string[] args)
  {
    ThreadPool.SetMinThreads(MaxThreads, 1);
    Console.WriteLine(ThreadPool.SetMaxThreads(MaxThreads, 1));
    Task.Run(() => SomeMethod(new StateInfo { Order = 0, WaitFor = 3000 }));
    Task.Run(() => SomeMethod(new StateInfo { Order = 1, WaitFor = 3000 }));
    Task.Run(() => SomeMethod(new StateInfo { Order = 2, WaitFor = 3000 }));
    Console.WriteLine("Main thread does some work, then sleeps.");
    Thread.Sleep(5000);
    Console.WriteLine("Main thread exits.");
  }

  static void SomeMethod(Object stateInfo)
  {
    var si = (StateInfo)stateInfo;
    Console.WriteLine($"Hello from the thread pool. {si.Order}");
    Thread.Sleep(si.WaitFor);
  }

  public class StateInfo
  {
    public int Order { get; set; }
    public int WaitFor { get; set; }
  }
}
输出

真的

主线程做一些工作,然后休眠

线程池中的你好。一,

线程池中的你好。二,

主线程退出

因为我们有一个线程,我们已经告诉前两个方法总共等待6秒,但是主线程在5秒后退出,所以我们从来没有收到来自第三个方法的消息。我们可以通过更改
MaxThreads=2
来轻松测试这一点,这会产生如下结果(我们得到3个结果,但不一定按顺序):

真的

主线程做一些工作,然后休眠

线程池中的你好。一,

线程池中的你好。二,

线程池中的你好。三,

主线程退出

既然我们已经保证使用单个线程,那么让我们看看我们可以同时同步执行多少个请求

因为我们不是异步/等待请求,所以它是同步运行的,因此输出是可预测的:

真的

主线程做一些工作,然后休眠

线程池中的你好。一,

线程池中的你好。1完成

线程池中的你好。二,

线程池中的你好。2完成

线程池中的你好。三,

线程池中的你好。3完成

主线程退出

这并不是真正的负载测试,因为同步调用要等到前一个调用完成。为了进行负载测试,我们需要许多并发调用。这可以通过使用async的单个线程轻松完成