alp*_*ler 3 c# multithreading task task-parallel-library
我有 2 个线程调用“Task.Factory.StartNew”。假设一个线程 (ThreadA) 比另一个线程 (ThreadB) 稍早一些。
... 在线程 A 中,稍微提前调用
Task.Run(() => {
SomeMethodInThreadA();
});
Run Code Online (Sandbox Code Playgroud)
... 在线程 B 中,稍后调用
Task.Run(() => {
SomeMethodInThreadB();
});
Run Code Online (Sandbox Code Playgroud)
TaskScheduler是否保证SomeMethodInThreadA在SomeMethodInThreadB之前先执行?
如果没有,我该怎么做?使用 Task.Factory.StartNew 并传入特殊的 TaskScheduler?
另外,除了保证先处理 SomeMethodInThreadA 之外,我还想确保SomeMethodInThreadA在执行SomeMethodInThreadB之前先完成。
我研究过使用StaTaskScheduler,但我不确定这是否是解决方案。
编辑:
在没有给出关于我继承的程序的太多细节/戏剧的情况下,我想我正在寻找的是一个自定义的 TaskScheduler,它:
当委托排队时尊重序列
串行执行它们
在同一个线程中执行,类似于我上面链接的 StaTaskScheduler 源代码
在没有给出关于我继承的程序的太多细节/戏剧的情况下,我想我正在寻找的是一个自定义的 TaskScheduler,它:
当委托排队时尊重序列
串行执行它们
在同一个线程中执行,类似于我上面链接的 StaTaskScheduler 源代码
如果这就是您想要的,那么您需要做的就是BlockingCollection<Action>在专用线程上循环遍历列表。
public class BackgroundJobSchedueller
{
readonly BlockingCollection<Action> _queue;
readonly Thread _thread;
public BackgroundJobSchedueller()
{
_queue = new BlockingCollection<Action>()
_thread = new Thread(WorkThread)
{
IsBackground = true,
Name = "Background Queue Processor"
};
_thread.Start();
}
public void StopSchedueller()
{
//Tell GetConsumingEnumerable() to let the user out of the foreach loop
// once the collection is empty.
_queue.CompleteAdding();
//Wait for the foreach loop to finish processing.
_thread.Join();
}
public void QueueJob(Action job)
{
_queue.Add(job);
}
void WorkThread()
{
foreach(var action in _queue.GetConsumingEnumerable())
{
try
{
action();
}
catch
{
//Do something with the exception here
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
当没有工作要做线程睡眠时,在 foreach 上被阻塞,一旦您将一个项目添加到队列中,它就会被处理然后重新进入睡眠状态。