简体   繁体   English

C#-多线程暂停

[英]C# - Multi-Threading Pause

Here's a code I made in C#: 这是我用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();
        }
    }
}

Now, the problem is, when the console says "5 seconds passed!" 现在的问题是,当控制台显示“ 5秒过去了!”时 (after aborting the t2 thread), it doesn't exit right away. (在中止t2线程后),它不会立即退出。 This text stays there for a couple of seconds and then the console exits. 该文本在那里停留了几秒钟,然后控制台退出。

The thing is, if I press a key (of the ReadKey method) before the thread aborts, it displays the "5 seconds passed!" 问题是,如果我在线程异常中止之前按了一个键( ReadKey方法的键),它将显示“ 5秒钟过去了!”。 text and then it exits right away. 文字,然后立即退出。

If I don't click any key, and the ReadKey method doesn't happen, it just displays the text for a couple of seconds. 如果我没有单击任何键,并且没有发生ReadKey方法,那么它将仅显示文本几秒钟。

Why is that? 这是为什么? Is it a bug? 是虫子吗? And can I fix it? 我可以修复它吗?

The result you are seeing seems reasonable to me, calling Thread.Abort isn't going to somehow unblock the Console so it will still be waiting for input. 您看到的结果对我来说似乎很合理,调用Thread.Abort不会以某种方式解除对控制台的阻止,因此它将仍在等待输入。 Regardless, you should avoid calling Thread.Abort as there is no guarantee that it will work as expected. 无论如何,您都应避免调用Thread.Abort因为无法保证它会按预期工作。 It's a much better approach to build cancellation support into your threads and there are various ways to do this. 这是在线程中建立取消支持的更好的方法,并且有多种方法可以执行此操作。

Alternatively, just use the Task Parallel Library which has it all build in already. 或者,只需使用已经全部内置的任务并行库

From your comments I see that you basically want to timeout the Console.ReadKey call after a certain amount of time. 从您的评论中,我看到您基本上想要在一定时间后使Console.ReadKey调用超时。 Unfortunately, ReadKey does not have a timeout parameter. 不幸的是, ReadKey没有超时参数。 That is okay. 没关系。 We can wrap it in a method that does. 我们可以将其包装在可以的方法中。 You do not need to use any asynchronous mechanisms to accomplish this. 您不需要使用任何异步机制来完成此任务。 Just use Console.KeyAvailable in a synchronous polling loop. 只需在同步轮询循环中使用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;
  }
}

And then you would use it like this. 然后您将像这样使用它。

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.
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM