运行 多个任务并行并覆盖 for 中的每一行
Running multiple tasks parrallel and overwriting each line in for
我是编程新手,但我有一个问题:
如何在控制台的不同行中显示不同的任务输出(我应该使用任务)?
另外,我想每次都覆盖这些行,所以输出应该显示:
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();
提前谢谢你:)
您需要为不同的任务同步访问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();
}
我是编程新手,但我有一个问题:
如何在控制台的不同行中显示不同的任务输出(我应该使用任务)? 另外,我想每次都覆盖这些行,所以输出应该显示:
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();
提前谢谢你:)
您需要为不同的任务同步访问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();
}