我已经为.net Core3.0Web应用程序做了一个干净的项目,我正在努力理解ThreadPool是如何在C#中工作的。
namespace TestASPSelf.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public static int countThread = 0;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
int workerThreads;
int portThreads;
ThreadPool.GetMaxThreads(out workerThreads, out portThreads);
Console.WriteLine("\nMaximum worker threads: \t{0}" +
"\nMaximum completion port threads: {1}",
workerThreads, portThreads);
ThreadPool.GetAvailableThreads(out workerThreads,
out portThreads);
Console.WriteLine("\nAvailable worker threads: \t{0}" +
"\nAvailable completion port threads: {1}\n",
workerThreads, portThreads);
Console.WriteLine("countThread = " + countThread);
return View();
}
class Z
{
public static void WaitTest(object o)
{
countThread++;
while (true)
{
Thread.Sleep(1000);
}
}
}
public IActionResult Privacy()
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("starting thread "+i);
ThreadPool.QueueUserWorkItem(new WaitCallback(Z.WaitTest));
}
return View();
}
}
}当http://localhost:5000/Home/Privacy打开时,它挂起一段时间(大约40-80秒),但我知道,它中的for循环逻辑几乎立即完成。当http://localhost:5000/打开之后,它也会挂起40-80秒,结果在控制台countThread = 100中。当线程启动时,app的CPU使用率约为5-10% .
我正在努力理解:
1)第一个原因是为什么ASP控制器每页挂起40-80秒,而CPU使用率为5-10 %时运行100个线程。CPU有很多资源,RAM也是免费的,但是为什么ASP控制器的页面方法是挂起的呢?
2)如何在运行线程数量有限的情况下在ThreadPool中创建C#?如果我正确理解方法public static bool SetMinThreads (int workerThreads, int completionPortThreads);,它会影响应用程序的所有线程。如何在活动线程数量有限的情况下创建ThreadPool对象,比如Java中的ExecutorService?例如,线程池的Java代码可能如下所示
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread("" + i);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}3)如何防止ASP控制器的所有方法挂起,并使“真正的”线程,如Java中的线程?
发布于 2019-10-22 11:11:19
ThreadPool.QueueUserWorkItem(new WaitCallback(Z.WaitTest));用这个你做了一件非常错误的事。您将导致线程池中的线程阻塞,因此池无法完成处理请求和处理新请求。
在某个时候,池中的一个线程设法返回并处理您的下一个请求,但是由于重载池,线程再次挂起。
至于你的其他问题,请解释一下你想要达到的目标。你的问题似乎试图解决一个不被理解的问题。
更新:在亚瑟的评论之后。
如果你要下载文件,你应该使用任务和异步等待.IO操作不消耗线程(更多的这里)。
创建N个任务,每个任务下载一个文件,然后等待Task.WhenAll。伪码:
List<Task> tasks = new List<Task>();
for (int i = 0; i < filesToDownloadCount; i++)
{
var t = new Task ( () => { /* ... code to download your file here ... */});
tasks.Add (t);
}
await t.WhenAll (tasks);这种方法将为您提供最佳的吞吐量,瓶颈将是您的带宽,而不是CPU。
发布于 2019-10-22 19:12:23
ThreadPool类有几个静态方法,包括当线程池工作线程可用时负责调用线程池工作线程的QueueUserWorkItem。如果线程池中没有可用的辅助线程,则等待线程可用。
using System;
using System.Threading;
class ThreadPoolSample
{
// Background task
static void BackgroundTask(Object stateInfo)
{
Console.WriteLine("Hello! I'm a worker from ThreadPool");
Thread.Sleep(1000);
}
static void BackgroundTaskWithObject(Object stateInfo)
{
Person data = (Person)stateInfo;
Console.WriteLine($"Hi {data.Name} from ThreadPool.");
Thread.Sleep(1000);
}
static void Main(string[] args)
{
// Use ThreadPool for a worker thread
ThreadPool.QueueUserWorkItem(BackgroundTask);
Console.WriteLine("Main thread does some work, then sleeps.");
Thread.Sleep(500);
// Create an object and pass it to ThreadPool worker thread
Person p = new Person("Mahesh Chand", 40, "Male");
ThreadPool.QueueUserWorkItem(BackgroundTaskWithObject, p);
int workers, ports;
// Get maximum number of threads
ThreadPool.GetMaxThreads(out workers, out ports);
Console.WriteLine($"Maximum worker threads: {workers} ");
Console.WriteLine($"Maximum completion port threads: {ports}");
// Get available threads
ThreadPool.GetAvailableThreads(out workers, out ports);
Console.WriteLine($"Availalbe worker threads: {workers} ");
Console.WriteLine($"Available completion port threads: {ports}");
// Set minimum threads
int minWorker, minIOC;
ThreadPool.GetMinThreads(out minWorker, out minIOC);
ThreadPool.SetMinThreads(4, minIOC);
// Get total number of processes availalbe on the machine
int processCount = Environment.ProcessorCount;
Console.WriteLine($"No. of processes available on the system: {processCount}");
// Get minimum number of threads
ThreadPool.GetMinThreads(out workers, out ports);
Console.WriteLine($"Minimum worker threads: {workers} ");
Console.WriteLine($"Minimum completion port threads: {ports}");
Console.ReadKey();
}
// Create a Person class
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Sex { get; set; }
public Person(string name, int age, string sex)
{
this.Name = name;
this.Age = age;
this.Sex = sex;
}
}
} https://stackoverflow.com/questions/58501643
复制相似问题