Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 item: {0} If I use string.Format() first, I don't have the problem. What is going on?

like image 694
Ronnie Overby Avatar asked Aug 05 '11 16:08

Ronnie Overby


People also ask

Is console WriteLine thread safe?

Answers. Yes, they are. Although TextWriter methods are not, Console. Out uses a SyncTextWriter which is thread-safe.

What does debug WriteLine do?

Definition. Writes information about the debug to the trace listeners in the Listeners collection.

Where does debug WriteLine write to?

Debug. WriteLine writes to the debug output. You can see it in your debugger and save it from there.


2 Answers

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.

like image 123
Jon Skeet Avatar answered Nov 15 '22 11:11

Jon Skeet


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}");
like image 22
Brock Avatar answered Nov 15 '22 11:11

Brock