开发者

Is Debug.WriteLine() thread safe?

Is Debug.WriteLine() thread safe?

According to this, it is thread safe. But, in my multithreaded program I am getting some strange output.

For example:

Code

// 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);

Output

"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."

You can see that things start going off the rails with ronnie's batch: Queued batch 开发者_如何学Pythonitem: {0} If I use string.Format() first, I don't have the problem. What is going on?


The problem is that you're not calling the overload you think you are. You're calling Debug.WriteLine(string, string) which uses the first parameter as the message and the second as a category, not a format argument.

The simplest way to fix this is to cast your argument to object to force it to use the Debug.WriteLine(string, params object[]) overload:

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

A slightly longer-winded approach, but one which is perhaps more object, is to explicitly create the array:

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

Or (just to keep supplying options :) call string.Format explicitly to call the Debug.WriteLine(string) overload:

Debug.WriteLine(string.Format("Queued batch item: {0}", bm.BatchName));

or when you're just including the argument directly at the end:

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

Alternatively, you might want to create your own convenience method which doesn't have the extra, unhelpful (in your case) overload.


I know this is an old thread and it's not super relevant to the question, but with newer versions of .NET you can also use the interpolation:

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

Also if you end up here, yes it is threadsafe. This is not, which I found out the hard way:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜