并行运行多个任务并覆盖for中的每一行

本文关键字:一行 for 运行 任务 覆盖 并行 | 更新日期: 2023-09-27 18:16:08

我对编程很陌生,但是我有一个问题:

如何在控制台的不同行中显示不同的任务输出(我应该使用任务) ?此外,我希望每次都覆盖这些行,因此输出应该显示:

i//每次重写这一行。

j//每次重写这一行。

我尝试使用SetCursorPosition,但它使任务输出之间的冲突。

一个小代码示例(希望这使它更清楚):

Task a = Task.Run(() =>
{
    int i;
    for (i = 0; i <= 1000000; i++)
    {
        Console.SetCursorPosition(Console.CursorLeft, 0); // ? 
        Console.WriteLine("{0}", i);
    }
});
Task b = Task.Run(() =>
{
    int j;
    for (j = 0; j <= 1000000; j++)
    {
        Console.SetCursorPosition(Console.CursorLeft, 3); // ?
        Console.WriteLine("{0}",j);
    }
});
Console.ReadLine();

提前感谢:)

并行运行多个任务并覆盖for中的每一行

您需要为不同的任务同步访问Console(如果有任何问题,我不固定位置部分,但明显的同步问题):

var consoleLock = new object();
Task.Run(() =>
{
    for (int i = 0; i <= 1000000; i++)
    {
        Thread.Sleep(1); // to simulate some work
        lock(consoleLock)
        {
            Console.SetCursorPosition(Console.CursorLeft, 0);
            Console.WriteLine(i);
        }
    }
});
Task.Run(() =>
{
    for (int j = 0; j <= 1000000; j++)
    {
        Thread.Sleep(1); // to simulate some work
        lock(consoleLock)
        {
            Console.SetCursorPosition(Console.CursorLeft, 3);
            Console.WriteLine(j);
        }
    }
});
Console.ReadLine();

这是您正在尝试的简化演示。根据需要修改

基本思想是,调用ThreadSafe方法从所有线程写入控制台。并且,每次更新控制台时,都要重写这两行(注意SetCursorPosition()方法的使用)。

static object locker = new object();
static int iCommon = 0;
static int jCommon = 0;
static void WriteText()
{
    lock(locker)
    {
        var text = string.Format("i = {0}{1}j = {2}", 
                                    iCommon, Environment.NewLine, jCommon);
        Console.SetCursorPosition(0, 
                                  Console.CursorTop == 0 ? 0 : Console.CursorTop - 1);
        Console.Write(text);
    }
}
static void Main(string[] args)
{
    Task a = Task.Run(() =>
    {
        for (int i = 0; i <= 15; i++)
        {
            Thread.Sleep(700); //just to demonstrate the display change
            iCommon = i;
            WriteText();
        }
    });
    Task b = Task.Run(() =>
    {
        for (int j = 0; j <= 10; j++)
        {
            Thread.Sleep(1150); //just to demonstrate the display change
            jCommon = j;
            WriteText();
        }
    });
    Console.ReadLine();
}