C# - 多线程暂停
本文关键字:暂停 多线程 | 更新日期: 2023-09-27 18:35:01
这是我用 C# 编写的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace xyz
{
class Program
{
Thread t1, t2;
static void Main(string[] args)
{
Program go = new Program();
go.actual();
}
public void actual()
{
t1 = new Thread(timer);
t2 = new Thread(inputting);
t1.Start();
t2.Start();
}
public void timer()
{
Thread.Sleep(5000);
t2.Abort();
Console.WriteLine("5 seconds passed!");
}
public void inputting()
{
Console.WriteLine("Please wait 5 seconds...");
Console.ReadKey();
}
}
}
现在,问题是,当控制台说"5 秒过去了!(中止t2
线程后(,它不会立即退出。此文本会在那里停留几秒钟,然后控制台退出。
问题是,如果我在线程中止之前按下(ReadKey
方法的(键,它会显示"5 秒过去了!"文本,然后立即退出。
如果我不单击任何键,并且ReadKey
方法没有发生,它只会显示文本几秒钟。
为什么?这是一个错误吗?我可以修复它吗?
您看到的结果对我来说似乎是合理的,调用Thread.Abort
不会以某种方式解锁控制台,因此它仍将等待输入。无论如何,您应该避免调用Thread.Abort
因为无法保证它会按预期工作。这是将取消支持构建到线程中的更好方法,并且有多种方法可以做到这一点。
或者,只需使用任务并行库,它已经内置了所有内容。
从您的评论中,我看到您基本上希望在一定时间后使Console.ReadKey
调用超时。遗憾的是,ReadKey
没有超时参数。没关系。我们可以将其包装在一个可以包装的方法中。您无需使用任何异步机制即可完成此操作。只需在同步轮询循环中使用Console.KeyAvailable
即可。
public static class ConsoleEx
{
public static bool TryReadKey(TimeSpan timeout, out ConsoleKeyInfo keyinfo)
{
var cts = new CancellationTokenSource();
return TryReadKey(timeout, cts.Token, out keyinfo);
}
public static bool TryReadKey(TimeSpan timeout, CancellationToken cancellation, out ConsoleKeyInfo keyinfo)
{
keyinfo = new ConsoleKeyInfo();
DateTime latest = DateTime.UtcNow.Add(timeout);
do
{
cancellation.ThrowIfCancellationRequested();
if (Console.KeyAvailable)
{
keyinfo = Console.ReadKey();
return true;
}
Thread.Sleep(1);
}
while (DateTime.UtcNow < latest);
return false;
}
}
然后你会像这样使用它。
public static void Main()
{
ConsoleKeyInfo cki;
if (ConsoleEx.TryReadKey(TimeSpan.FromSeconds(5), out cki))
{
Console.WriteLine("ReadKey returned a value.");
}
else
{
Console.WriteLine("ReadKey timed out.
}
}