在 C# 中告诉 "other" 任务暂停
Telling "other" Tasks to pause in C#
我有以下内容:
[TestMethod]
public async Task Start()
{
var numDrivers = 2;
List<Task> tasks = new List<Task>();
var motherDriver = GetMotherDriver();
while (numDrivers != 0)
{
var rnd = new Random();
var r = rnd.Next(itemArray.Count);
var target = itemArray[r];
var proxyDriver = GetProxiedDriver();
tasks.Add(Task.Run(() => HandleIntro(proxyDriver)));
numDrivers--;
}
await Task.WhenAll(tasks);
}
这是有效的,但每隔一段时间,HandleIntro
会遇到一个需要 motherDriver
重置的错误。通常,如果 proxyDriver
中的一个命中这种情况,所有这些都会立即发生。我需要防止 motherDriver
多次重生,所以我尝试使用布尔 isPaused
和 while
循环来管理它。在 HandleIntro
中,我尝试使用第一个任务设置的全局变量来告诉其他任务暂停直到完成:
private bool _isPaused;
private async Task Start(){
_isPaused = false;
//code
}
private async Task HandleIntro(Driver driver) {
// wait for isPaused to get set to false
while(_isPaused){}
// do stuff
if(errorOccurs){
FixProblem();
}
}
private void FixProblem(){
if (!_isPaused){
_isPaused = true;
// spawn new motherDriver
_isPaused = false;
} else{
// hold here until other thread sets isPaused = false
while (_isPaused){}
}
}
但编译器告诉我 FixProblem
中的 while (_isPaused)
始终是 true
- 好像它没有看到该值将在某个时候由另一个线程设置观点。这告诉我,我正在以错误的方式解决这个问题。这是正确的方法吗?如何妥善处理?
将 volatile
关键字添加到 _isPaused
字段可能会解决问题,但我建议使用 lock
.
的适当同步
您正在跨各种任务共享 _isPaused
变量。因此,当一个任务改变变量的值时;所有线程进入新的motherDriver
初始化过程。
您需要同步访问重启motherDriver
控制块以确保只有一个线程可以重启进程。尝试类似的东西:
private static object objectlock = new object();
private void FixProblem(){
lock(objectlock)
{
if (!_isPaused && motherDriverNeedsTobeRestarted){
_isPaused = true;
// spawn new motherDriver
_isPaused = false;
}
}
}
这将确保在出现问题时 motherDriver
在任务关闭之前重新启动。
我有以下内容:
[TestMethod]
public async Task Start()
{
var numDrivers = 2;
List<Task> tasks = new List<Task>();
var motherDriver = GetMotherDriver();
while (numDrivers != 0)
{
var rnd = new Random();
var r = rnd.Next(itemArray.Count);
var target = itemArray[r];
var proxyDriver = GetProxiedDriver();
tasks.Add(Task.Run(() => HandleIntro(proxyDriver)));
numDrivers--;
}
await Task.WhenAll(tasks);
}
这是有效的,但每隔一段时间,HandleIntro
会遇到一个需要 motherDriver
重置的错误。通常,如果 proxyDriver
中的一个命中这种情况,所有这些都会立即发生。我需要防止 motherDriver
多次重生,所以我尝试使用布尔 isPaused
和 while
循环来管理它。在 HandleIntro
中,我尝试使用第一个任务设置的全局变量来告诉其他任务暂停直到完成:
private bool _isPaused;
private async Task Start(){
_isPaused = false;
//code
}
private async Task HandleIntro(Driver driver) {
// wait for isPaused to get set to false
while(_isPaused){}
// do stuff
if(errorOccurs){
FixProblem();
}
}
private void FixProblem(){
if (!_isPaused){
_isPaused = true;
// spawn new motherDriver
_isPaused = false;
} else{
// hold here until other thread sets isPaused = false
while (_isPaused){}
}
}
但编译器告诉我 FixProblem
中的 while (_isPaused)
始终是 true
- 好像它没有看到该值将在某个时候由另一个线程设置观点。这告诉我,我正在以错误的方式解决这个问题。这是正确的方法吗?如何妥善处理?
将 volatile
关键字添加到 _isPaused
字段可能会解决问题,但我建议使用 lock
.
您正在跨各种任务共享 _isPaused
变量。因此,当一个任务改变变量的值时;所有线程进入新的motherDriver
初始化过程。
您需要同步访问重启motherDriver
控制块以确保只有一个线程可以重启进程。尝试类似的东西:
private static object objectlock = new object();
private void FixProblem(){
lock(objectlock)
{
if (!_isPaused && motherDriverNeedsTobeRestarted){
_isPaused = true;
// spawn new motherDriver
_isPaused = false;
}
}
}
这将确保在出现问题时 motherDriver
在任务关闭之前重新启动。