Problem with .Net Console

I am just learning how to work with Threading in C #. I took an example from msdn and modified it to create a simple game like this. But the problem is that the while loop in the DoWork method reads the keys before the DoWork method is called from the main program. I, e. When you run the program, before the message “Go:” appears on the screen, if you type something, and the loop in the DoWork method reads the keys. But control should be passed to the while loop after printing “Go:” on the screen, on the right. Can someone kindly explain to me why this happens this way. Thank.

 public class Worker    
{
  ConsoleKeyInfo cki;  
  StringBuilder sb = new StringBuilder();
  bool f = true;

// This method will be called when the thread is started.
public void DoWork()
{
    Console.SetCursorPosition(49, 8);
    Console.Write("Go:");
    Console.SetCursorPosition(53, 8);

    while (!_shouldStop)
    {         
       cki = Console.ReadKey(true);
       if (f == true && (65 <= Convert.ToInt32(cki.Key) && Convert.ToInt32(cki.Key) <= 90))
       {
           Console.Write(cki.Key.ToString());               
           sb.Append(cki.Key.ToString());
       }  
    }
    while (true)
    {
        if (cki.Key.ToString() == "Enter") break;
        cki = Console.ReadKey(true);
        if (cki.Key.ToString() == "Enter") break;
    }
}
public void RequestStop(string word)
{
    _shouldStop = true;
    f =false;
    Console.WriteLine();
    Console.SetCursorPosition(44, 10);
    Console.WriteLine("- TIME OUT -");
    Console.SetCursorPosition(46, 12);
    if (sb.ToString() == word.ToUpper())
    {
        Console.WriteLine("CORRECT !");
        Console.SetCursorPosition(42, 13);
        Console.WriteLine("CONGRATULATIONS");
    }
    else { Console.SetCursorPosition(47, 12); Console.WriteLine("WRONG !"); }
    Console.SetCursorPosition(40, 15);
    Console.WriteLine("Press [Enter] to quit");
    Console.CursorVisible = false;
}

 private volatile bool _shouldStop;

}

public class WordPlay
{
  static void Main()
  {
    Console.SetBufferSize(100,50);
    Console.SetWindowSize(100,50);
    string[] words = { "angstrom", "abacinate", "abactinal", "abandoned", "Babesiidae", "babirussa", "Babylonian", "bacchantic", "cabassous", "cableway" };
    string word="";      
    Random randObj = new Random(0);
    Console.SetCursorPosition(40, 6);
    Console.WriteLine("Your String:");
    Console.WriteLine();       
    for (int j = 0; j < 20; j++)
    { 
       System.Threading.Thread.Sleep(150); Console.SetCursorPosition(53, 6); 
       Console.Write(words[randObj.Next(words.Length - 1)].ToUpper() + "     ");  
    }

    word = words[randObj.Next(words.Length - 1)].ToUpper();
    Console.SetCursorPosition(53, 6);
    Console.Write( word+"    ");
    Console.WriteLine();

    // Create the thread object. This does not start the thread.
    Worker workerObject = new Worker();
    Thread workerThread = new Thread(workerObject.DoWork);

    // Start the worker thread.
    workerThread.Start();

    // Loop until worker thread activates.
    while (!workerThread.IsAlive);

    // Put the main thread to sleep for 1 millisecond to
    // allow the worker thread to do some work:

    Thread.Sleep(3000);
    // Request that the worker thread stop itself:

    workerObject.RequestStop(word);

    // Use the Join method to block the current thread 
    // until the object thread terminates.

    workerThread.Join();      
}

}

+3
source share
7 answers

. ReadKey(); . , .

0

Joe Albahari - .

+3

. .

, Console, ReadKey() .

+3

1 , . Thread , , .

Threading # 1:

Threads .

+2
+1

Console.Out.Flush()? , .

+1

, , , BackgroundWorker, . , , - , - SplashScreen . BackgroundWorker .

using System.ComponentModel.Component;

private BackgroundWorker newThread = new BackgroundWorker();

public void appForm_Load(object sender, EventArgs e) {
    SplashForm sf = new SplashForm();
    sf.Parent = this;

    newThread.DoWork += new EventHandler(newThread_DoWork);
    newThread.RunWorkerAsync(); // Here starts the thread.

    sf.ShowDialog(); // Then shows your splash screen.
}

public void newThread_DoWork(object sender, DoWorkEventArgs e) {
    // TODO: Place the code required by yours tasks here, or call another method to do so.
}

. , , , . ProgressBar, SplashForm BackgroundWorker.ProgressChanged(). Dispose() SplashForm BackgroundWorker. BackgroundWorker.RunWorkerCompleted().

, SplashForm appForm_Load(), BackgroundWorker.RunWorkerCompleted() , .

This, in my opinion, is humbly, the most efficient and easiest way to do multithreading. BackgroundWorker is very convenient for programmers, without worrying about blocking, delegation, calls and callbacks.

The .NET Framework 4 should have many tools to facilitate multithreading: Threadsafe collections, parallel LINQs, etc.

+1
source

Source: https://habr.com/ru/post/1735033/


All Articles