C# 如何在指定的线程中运行异步方法
我有一个应用程序(http web负载测试应用程序)需要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 ()=> {
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的单个线程轻松完成