我是编程新手,目前我正在努力学习c#。这是我的问题: 我有以下代码:
static void Main()
{
string loading = "LOADING...";
for (int i = 0; i < 5; i++)
{
foreach (var letter in loading)
{
Console.Write("{0}", letter);
Thread.Sleep(250);
}
Console.Clear();
Console.Write("\r");
}
for (int k = 0; k <= 100; k++)
{
Console.Write("\r{0}%", k);
Thread.Sleep(150);
}
}
我试图找到一种同时执行这两个for循环的方法。我想继续在控制台上重写LOADING并在其下面打印从1到100的百分比。现在第二个for循环在第一次退出后运行。是否有可能让它们同时运行?我一直试图找几个小时的答案,但到目前为止没有运气。 谢谢!
答案 0 :(得分:1)
正如krillgar所说,你可以使用Tasks独立运行每个循环。像这样:
string loading = "LOADING...";
var loadingTask = Task.Run(() =>
{
for (int i = 0; i < 5; i++)
{
foreach (var letter in loading)
{
Console.Write("{0}", letter);
Thread.Sleep(250);
}
Console.Clear();
Console.Write("\r");
}
});
var pocTask = Task.Run(() =>
{
for (int k = 0; k <= 100; k++)
{
Console.Write("\r{0}%", k);
Thread.Sleep(150);
}
});
Task.WaitAll(loadingTask, pocTask);
请注意,它不会像你期望的那样工作(第一行有LOADING ......第二行有百分比)。这需要在这些循环之间对显示的消息进行一些同步,我认为这完全是另一个故事而不是你问题答案的范围。
答案 1 :(得分:0)
除了在两个线程中运行代码之外,还有更多挑战。当多个线程同时尝试写入控制台时,您很可能会遇到竞争条件,其中一个线程开始在另一个线程的输出中间写入。
为防止这种情况发生,您需要强制执行关键部分,这些部分是代码中只能有一个线程可以随时执行的区域。这些通常包括:
// Critical section
lock (syncLock)
{
Console.SetCursorPosition(x, y);
Console.Write(yourText);
}
Thread.Sleep(yourDelay);
以下是完整代码:
// Dummy object to serve as mutual-exclusion lock when synchronizing threads.
private static readonly object syncLock = new object();
public static void Main(string[] args)
{
// Run two anonymous functions in parallel,
// then wait for both to complete.
Parallel.Invoke(
// Anonymous function for printing "LOADING..."
() =>
{
const string loading = "LOADING...";
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < loading.Length; j++)
{
// Critical section
lock (syncLock)
{
Console.SetCursorPosition(j, 0);
Console.Write("{0}", loading[j]);
}
Thread.Sleep(250);
}
// Critical section
lock (syncLock)
{
Console.SetCursorPosition(0, 0);
Console.Write("\r ");
}
Thread.Sleep(250);
}
},
// Anonymous function for printing "x%"
() =>
{
for (int k = 0; k <= 100; k++)
{
// Critical section
lock (syncLock)
{
Console.SetCursorPosition(0, 1);
Console.Write("\r{0}%", k);
}
Thread.Sleep(150);
}
});
}
}