Debug.WriteLine() 是线程安全的吗?

6

Debug.WriteLine() 是线程安全的吗?

根据 这里 的说明,它是线程安全的。但是,在我的多线程程序中,我得到了一些奇怪的输出。

例如:

代码

// these statements are found throughout the program
Debug.WriteLine("Polled database. {0} batch items retrieved.", items.Count());
Debug.WriteLine("Queued batch item: {0}", bm.BatchName);
Debug.WriteLine("Discarded batch item: {0} already queued.", bm.BatchName);
Debug.WriteLine("Creating task for batch item: {0}", bm.BatchName);
Debug.WriteLine("Removed batch item from processing items collection: {0}", bm.BatchName);
Debug.WriteLine("Could not remove batch item from processing items collection: {0}", bm.BatchName);
Debug.WriteLine("Begin Processing: {0}", bm.BatchName);
Debug.WriteLine("End Processing: {0}", bm.BatchName);

输出

"Polled database. 0 batch items retrieved."
"Polled database. 0 batch items retrieved."
"Polled database. 0 batch items retrieved."
"Polled database. 0 batch items retrieved."
"Polled database. 1 batch items retrieved."
"ronnie's batch: Queued batch item: {0}"
"ronnie's batch: Creating task for batch item: {0}"
"Begin Processing: ronnie's batch"
"Polled database. 1 batch items retrieved."
"ronnie's batch: Discarded batch item: {0} already queued."
"End Processing: ronnie's batch"
"ronnie's batch: Removed batch item from processing items collection: {0}"
"Polled database. 0 batch items retrieved."

你可以看到,当使用 ronnie's batch: Queued batch item: {0} 时,出现了问题。如果我先使用 string.Format(),就不会有这个问题。是什么原因导致的呢?

2个回答

12
问题在于你没有调用你认为的重载方法。你正在调用的是 Debug.WriteLine(string, string),它使用第一个参数作为消息,第二个参数作为类别而不是格式参数。
最简单的解决方法是将你的参数转换为object类型,以强制使用Debug.WriteLine(string, params object[])重载:
Debug.WriteLine("Queued batch item: {0}", (object) bm.BatchName);

另一种稍微冗长但更加面向对象的方法是显式地创建该数组:

Debug.WriteLine("Queued batch item: {0}", new object[] { bm.BatchName });

或者(只是为了提供更多选项 :) 明确调用string.Format来调用Debug.WriteLine(string)重载:

Debug.WriteLine(string.Format("Queued batch item: {0}", bm.BatchName));
或者当您直接将参数包含在结尾时:

或者当您直接将参数包含在结尾时:

Debug.WriteLine("Queued batch item: " + bm.BatchName);

或者,您可能需要创建自己的便利方法,带有额外的、在您的情况下没有作用的重载。


谢谢,Jon。我应该循环使用这些重载! - Ronnie Overby
现在,这才是我所说的答案! - Ronnie Overby
最终选项是否可行?我认为你会想要从文字中删除 {0} - dlev
@dlev:糟糕,这就是匆忙的问题...感谢Ronnie的编辑。 - Jon Skeet

1

我知道这是一个旧的帖子,与问题不太相关,但在较新版本的.NET中,您还可以使用插值:

Debug.WriteLine($"Queued batch item: {bm.BatchName}");

如果你在这里,那么是线程安全的。但是我通过艰难的方式发现,这个不是线程安全的:
Console.WriteLine($"Queued batch item: {bm.BatchName}");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接