Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PromptPlus output becomes messy from inside Parallel.ForEach or Parallel.Invoke functions #121

Open
ividyon opened this issue Jan 13, 2024 · 4 comments
Assignees

Comments

@ividyon
Copy link
Contributor

ividyon commented Jan 13, 2024

Tested with simple WriteLine.

From inside Parallel:

2024-01-13_12-01-33__WindowsTerminal

Without Parallel:

2024-01-13_12-07-45__WindowsTerminal

@FRACerqueira
Copy link
Owner

Hello ivideon,
This behavior does not depend on the implementation of Prompt Plus but on the concept of parallelism functions that do not guarantee the execution sequence. Once prompplus knows what it will write to the console (stream out) it sends it to the default provider which "prints" the result. As the "print" does not have a guarantee of sequence due to parallelism, the result is confusing.

In other words, console operations do not work well with multi-threads unless the application itself manages the result and organizes the data before sending it to the console.

Try this and see the result (it will be confusing too)

        static void Main(string[] args)
        {
            Console.Clear();
            Console.WriteLine("write 100 line Without Parallel:");
            for (int i = 0; i < 100; i++) 
            {
                Console.Write("test Console.Write ");
                Console.WriteLine($"value is {i} ");

            }
            Console.WriteLine("Press Any Key");
            Console.ReadKey(false);
            Console.Clear();
            Console.WriteLine("write 100 line From inside Parallel.for:");
            Parallel.For(1,100,(i) =>
            {
                Console.Write("test Console.Write ");
                Console.WriteLine($"value is {i} ");
            });
        }

@ividyon
Copy link
Contributor Author

ividyon commented Jan 16, 2024

Looks like this can be improved with the following:

internal static class Program
{
    internal static object ConsoleWriterLock = new object();

    static void Main(string[] args)
    {
        Console.Clear();
        Console.WriteLine("write 100 line Without Parallel:");
        for (int i = 0; i < 100; i++)
        {
            Console.Write("test Console.Write ");
            Console.WriteLine($"value is {i} ");
        }

        Console.WriteLine("Press Any Key");
        Console.ReadKey(false);
        Console.Clear();

        Console.WriteLine("write 100 line From inside Parallel.for:");
        Parallel.For(1, 100, (i) =>
        {
            lock (ConsoleWriterLock)
            {
                Console.Write("test Console.Write ");
                Console.WriteLine($"value is {i} ");
            }
        });
    }
}

Before:
2024-01-16_07-52-29__rider64

After:
2024-01-16_07-52-53__rider64

Using lock() {} with a static readonly object makes the output orderly during parallel processing, at (assumably) the cost of a bit of parallel performance (but we're probably talking microseconds here).

Some kind of PromptPlus.LockOutput boolean which enables such behavior, as well as access to a public PromptPlus.ConsoleLock object which is used for this (for making their own custom locks) could be great and save users the effort of wrapping each of their own Writes.

@ividyon ividyon closed this as completed Jan 16, 2024
@ividyon ividyon reopened this Jan 16, 2024
@ividyon
Copy link
Contributor Author

ividyon commented Jan 16, 2024

Pressed the wrong button...

@ividyon
Copy link
Contributor Author

ividyon commented Mar 4, 2024

I'll also note that this issue doesn't occur if you do .Write("MyString" + "\n") instead of WriteLine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants