【发布时间】:2020-04-25 06:19:01
【问题描述】:
我正在使用下面的代码在 C# 中创建多个任务:
private static List<Task> _taskList = new List<Task>();
private static ConcurrentQueue<string> cred = new ConcurrentQueue<string>();
private static void TaskMethod1(string usercred)
{
// I am doing a bunch of operations here, all of them can be replaced with
// a sleep for 25 minutes.
// After all operations are done, enqueue again.
cred.Enqueue("usercred")
}
private static void TaskMethod()
{
while(runningService)
{
string usercred;
// This will create more than one task in parallel to run,
// and each task can take up to 30 minutes to finish.
while(cred.TryDequeue(out usercred))
{
_taskList.Add(Task.Run(() => TaskMethod1(usercred)));
}
}
}
internal static void Start()
{
runningService = true;
cred.enqueue("user1");
cred.enqueue("user2");
cred.enqueue("user3");
Task1 = Task.Run(() => TaskMethod());
}
我在上面的代码中遇到了一个奇怪的行为。通过在_taskList.Add(Task.Run(() => TaskMethod1(usercred))); 行放置一个断点,我每次调用TaskMethod1 时都会检查usercred 的值,并且在调用时它不为空,但在其中一种情况下usercred 的值是null 内部TaskMethod1。我不知道这是怎么发生的。
【问题讨论】:
-
我怀疑你收到了captured variable problem。请在方法 TaskMethod 中添加显示变量 arg1 的所有用法的代码。
-
用显示TaskMethod中变量用法的代码编辑。
-
您能否将
while(cred.TryDequeue(out usercred)) { _taskList.Add(Task.Run(() => TaskMethod1(usercred))); }更改为while(cred.TryDequeue(out usercred)) { var uc = usercred; _taskList.Add(Task.Run(() => TaskMethod1(uc))); }并让我们知道问题是否消失? -
这个问题是否只在附加调试器时出现,在您使用 Ctrl+F5(不调试)运行程序时消失?我之所以问,是因为您提到了一个断点,并且调试器在多线程代码中不是 100% 可信赖的。
-
你也知道
TaskMethod方法会创建一个紧密的循环吗?
标签: c# multithreading multitasking