ayush
ayush

Reputation: 14568

Multithreading in c# - Replicate Console class behaviour

I have an application that executed 4 function sequentially. Inside each function I have outputs that are logged using console.writeline. The console internally is made to redirect all data to a file.

I have to change the working so that all four functions can be run in parallel. Everything else being fine my concern is about the output logging in the file. console.writeline will now write data in the file in a random order which I don't want. I want all the threads to finish and then log the output from all the data in the sequence that I want.

So how do I capture the output inside each thread?

  1. In a string and then do console.writeline for all the 4 string that I make?
  2. Capture data in a file for each thread and the do console.writeline when all thread finish.
  3. Some other class like Console where the data is read/written in the same way as Console class?

I basically want the output to be exactly same as how it was earlier when the application was running all function sequentially.

Upvotes: 0

Views: 114

Answers (3)

Jim Mischel
Jim Mischel

Reputation: 133995

If you know that all of your output will fit in memory, then you can write the output to strings and then append those strings to a file when done.

There are many ways to output to string. For your purposes, perhaps the easiest would be to create a StringWriter for each thread. For example:

StringWriter output = new StringWriter();

Then, replace all of your Console.WriteLine calls to output.WriteLine.

When your thread has finished, it can convert the output to a string by calling ToString. That is:

string threadOutput = output.ToString();

Then take each thread's output and write to the file in the order you want.

If the output is too large to fit in memory, then have each thread open a StreamWriter, which will write to file. When the four threads are done, you can open each of the files in turn, read the data, and write to the output. Something like:

using (FileStream outputFile = File.OpenWrite(outputFileName))
{
    // do the following for each thread's output
    using (FileStream threadFile = File.OpenRead(inputFilename))
    {
        threadFile.CopyTo(outputFile);
    }
}

Upvotes: 2

faceman
faceman

Reputation: 1328

You should have a look at the Task Parallel Library (TPL).

You could then start several tasks, wait until all completed and then print their results (e.g. strings) in the sequence you like....

This is from the msdn docs (MSDN TPL):

Wait until all tasks finished:

// Wait for all tasks to complete.
Task[] tasks = new Task[10];
for (int i = 0; i < 10; i++)
{
   tasks[i] = Task.Factory.StartNew(() => DoSomeWork(10000000));
}
Task.WaitAll(tasks);

Task with return value:

// Return a value type with a lambda expression
Task<string> task1 = Task<string>.Factory.StartNew(() => "some text");
int i = task1.Result;

Upvotes: 1

Hadron
Hadron

Reputation: 501

As I understand it, these four methods are always called together, so what you could do is each time you call them, first you append four empty lines to your log file, and then each method can write it's own output on a predetermined line relatively to the number of line in the log file. That would be if you absolutely wanted not to wait for all method to finish.

But since accessing files is longer than writing the values in a string, I would recommand that you use a string array or something similar:

string[] output = new string[4];
private void method1()
{
    output[1] = some_stuff.ToString();
}
...

and when all threads are over you write them all at once

foreach (string s in output) Console.WriteLine(s);

that's pretty much the simplest and quickest thing to do.

Upvotes: -1

Related Questions