【发布时间】:2018-08-25 09:59:36
【问题描述】:
有没有办法指定每个方法使用的核心/线程数并且不阻塞它们。 例子: 我有方法A和方法B。 方法 A 会被调用 50 次,方法 B 也会被调用。
假设我有一个 16 核的 CPU。 我想将其委托给方法 A 它将并行使用 2 个线程,而方法 B 将使用 4 个线程并且不会阻塞它们。 我尝试过使用信号量,但在任务执行后它们会阻塞和释放。
这里是一些示例代码: 注意:threadService 方法只是调用 Thread.Sleep 3 秒
static void Main(string[] args)
{
ThreadService threadService = new ThreadService();
for (int i = 0; i < 5; i++)
{
Task t = Task.Run(() => threadService.RunFirstMethod());
}
for (int i = 0; i < 5; i++)
{
Task t = Task.Run(() => threadService.RunSecondMethod());
}
Console.ReadLine();
}
也许这不是一个好主意...?任何帮助或建议将不胜感激。 谢谢。
信号量的第一次尝试(不行):
static void Main(string[] args)
{
ThreadService threadService = new ThreadService();
Semaphore semaphoreFirstMethod = new Semaphore(2, 2);
for (int i = 0; i < 5; i++)
{
semaphoreFirstMethod.WaitOne();
Task t = Task.Run(() => threadService.RunFirstMethod()).ContinueWith(s => semaphoreFirstMethod.Release());
}
Semaphore semaphoreSecondMethod = new Semaphore(2,2);
for (int i = 0; i < 5; i++)
{
semaphoreSecondMethod.WaitOne();
Task t = Task.Run(() => threadService.RunSecondMethod()).ContinueWith(s => semaphoreSecondMethod.Release());
}
Console.ReadLine();
}
结果如下:
2018-08-25 15:34:17.7259 INFO RunFirstMethod()
2018-08-25 15:34:17.7259 INFO RunFirstMethod()
2018-08-25 15:34:19.7691 INFO RunFirstMethod()
2018-08-25 15:34:19.7691 INFO RunFirstMethod()
2018-08-25 15:34:21.7775 INFO RunFirstMethod()
2018-08-25 15:34:21.7775 INFO RunSecondMethod()
2018-08-25 15:34:21.7775 INFO RunSecondMethod()
2018-08-25 15:34:23.8053 INFO RunSecondMethod()
2018-08-25 15:34:23.8053 INFO RunSecondMethod()
2018-08-25 15:34:25.8211 INFO RunSecondMethod()
在@mjwills 建议使用 sempahores 发布代码后,我发现我没有做应有的事情, 信号量的第二次实现:
static void Main(string[] args)
{
ThreadService threadService = new ThreadService();
Task.Run(() =>
{
Semaphore semaphore = new Semaphore(2, 2);
for (int i = 0; i < 5; i++)
{
semaphore.WaitOne();
Task t = Task.Run(() => threadService.RunFirstMethod()).ContinueWith(s => semaphore.Release());
}
});
Task.Run(() =>
{
Semaphore semaphore = new Semaphore(2, 2);
for (int i = 0; i < 5; i++)
{
semaphore.WaitOne();
Task t = Task.Run(() => threadService.RunSecondMethod()).ContinueWith(s => semaphore.Release());
}
});
Console.ReadLine();
}
第二个结果(对我来说没问题):
2018-08-25 15:36:01.0845 INFO RunSecondMethod()
2018-08-25 15:36:01.0855 INFO RunFirstMethod()
2018-08-25 15:36:02.0863 INFO RunFirstMethod()
2018-08-25 15:36:03.0783 INFO RunSecondMethod()
2018-08-25 15:36:03.1386 INFO RunSecondMethod()
2018-08-25 15:36:03.1386 INFO RunFirstMethod()
2018-08-25 15:36:04.0938 INFO RunFirstMethod()
2018-08-25 15:36:05.0877 INFO RunSecondMethod()
2018-08-25 15:36:05.1547 INFO RunSecondMethod()
2018-08-25 15:36:05.1677 INFO RunFirstMethod()
【问题讨论】:
-
你能举个例子吗?我无法理解您的要求:/
-
你的方法实际上会做什么?计算、从一些外部资源(数据库、网络服务等)加载数据?
-
@Fabio 从外部资源加载数据并处理它们并发布
-
从外部资源加载数据不需要多线程。您可以在一个线程上“同时”加载数据(当您加载数据时,您的线程什么都不做 - 只等待响应 - 这将浪费资源。然后对于处理数据,您可以使用Task Parallel Library (TPL)
-
@Fabio 是的,但在我的情况下,每个线程实际上是独立的,每个线程都会加载、处理不同的数据。每个人都会为特定的客户做特定的工作
标签: c# multithreading task-parallel-library