Bus*_*ist 0 c# semaphore multitasking
我需要同时完成5个任务,一次执行最多2个任务.因此,一旦某个任务完成,下一个应该运行,直到没有任务待处理.
我正在使用LB的解决方案,该解决方案涉及使用信号量来跨任务同步.
void LaunchTaskPool ()
{
SemaphoreSlim maxThreadSemaphore = new SemaphoreSlim(2); //Max 2 tasks at a time.
for (int i = 0; i < 5; i++) //loop through 5 tasks to be assigned
{
maxThreadSemaphore.Wait(); //Wait for the queue
Console.WriteLine("Assigning work {0} ", i);
Task t = Task.Factory.StartNew(() =>
{
DoWork(i.ToString()); // assign tasks
}, TaskCreationOptions.LongRunning
)
.ContinueWith(
(task) => maxThreadSemaphore.Release() // step out of the queue
);
}
}
void DoWork(string workname)
{
Thread.Sleep(100);
Console.WriteLine("--work {0} starts", workname);
Thread.Sleep(1000);
Console.WriteLine("--work {0} finishes", workname);
}
Run Code Online (Sandbox Code Playgroud)
问题是一些随机任务甚至无法启动.例如,工作1和3从未开始,工作4运行两次:
我尝试在这里建议添加Task.WaitAll(),但它没有帮助.
提前感谢您的建议!
康斯坦丁.
我推荐使用Parallel.For()这个; 没有必要重新发明轮子!您可以MaxDegreeOfParallelism在使用时指定Parallel.For():
例如:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp4
{
class Program
{
static void Main()
{
Parallel.For(
0, // Inclusive start
5, // Exclusive end
new ParallelOptions{MaxDegreeOfParallelism = 2},
i => DoWork(i.ToString()));
}
static void DoWork(string workname)
{
Thread.Sleep(100);
Console.WriteLine("--work {0} starts", workname);
Thread.Sleep(1000);
Console.WriteLine("--work {0} finishes", workname);
}
}
}
Run Code Online (Sandbox Code Playgroud)
(实际上我只是看了,这已经是你所链接的主题中的其他答案之一 - 你是否有理由不想使用该解决方案?如果没有,我想我们应该把这个问题作为重复来关闭. ..)
无论如何要回答你的实际问题:
您正在循环中访问"修改后的闭包".要解决此问题,请在将循环变量i传递给任务之前复制它:
SemaphoreSlim maxThreadSemaphore = new SemaphoreSlim(2); //Max 2 tasks at a time.
for (int i = 0; i < 5; i++) //loop through 5 tasks to be assigned
{
maxThreadSemaphore.Wait(); //Wait for the queue
Console.WriteLine("Assigning work {0} ", i);
int copy = i; // <----- Make a copy here.
Task t = Task.Factory.StartNew(() =>
{
DoWork(copy.ToString()); // assign tasks
}, TaskCreationOptions.LongRunning
)
.ContinueWith(
(task) => maxThreadSemaphore.Release() // step out of the queue
);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
230 次 |
| 最近记录: |