簡體   English   中英

C#-多線程暫停

[英]C# - Multi-Threading Pause

這是我用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.
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM