.NET: How to have background thread signal main thread data is available?

后端 未结 7 1964
终归单人心
终归单人心 2021-02-14 04:54

What is the proper technique to have ThreadA signal ThreadB of some event, without having ThreadB sit blocked waiting for an e

相关标签:
7条回答
  • 2021-02-14 05:12

    Here's a code sample for the System.ComponentModel.BackgroundWorker class.

        private static BackgroundWorker worker = new BackgroundWorker();
        static void Main(string[] args)
        {
            worker.DoWork += worker_DoWork;
            worker.RunWorkerCompleted += worker_RunWorkerCompleted;
            worker.ProgressChanged += worker_ProgressChanged;
            worker.WorkerReportsProgress = true;
    
            Console.WriteLine("Starting application.");
            worker.RunWorkerAsync();
    
            Console.ReadKey();
        }
    
        static void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            Console.WriteLine("Progress.");
        }
    
        static void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            Console.WriteLine("Starting doing some work now.");
    
            for (int i = 0; i < 5; i++)
            {
                Thread.Sleep(1000);
                worker.ReportProgress(i);
            }
        }
    
        static void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Console.WriteLine("Done now.");
        }
    
    0 讨论(0)
  • 2021-02-14 05:15

    The BackgroundWorker class is answer in this case. It is the only threading construct that is able to asynchronously send messages to the thread that created the BackgroundWorker object. Internally BackgroundWorker uses the AsyncOperation class by calling the asyncOperation.Post() method.

    this.asyncOperation = AsyncOperationManager.CreateOperation(null);
    this.asyncOperation.Post(delegateMethod, arg);
    

    A few other classes in the .NET framework also use AsyncOperation:

    • BackgroundWorker
    • SoundPlayer.LoadAsync()
    • SmtpClient.SendAsync()
    • Ping.SendAsync()
    • WebClient.DownloadDataAsync()
    • WebClient.DownloadFile()
    • WebClient.DownloadFileAsync()
    • WebClient...
    • PictureBox.LoadAsync()
    0 讨论(0)
  • 2021-02-14 05:18

    If your "main" thread is the Windows message pump (GUI) thread, then you can poll using a Forms.Timer - tune the timer interval according to how quickly you need to have your GUI thread 'notice' the data from the worker thread.

    Remember to synchronize access to the shared List<> if you are going to use foreach, to avoid CollectionModified exceptions.

    I use this technique for all the market-data-driven GUI updates in a real-time trading application, and it works very well.

    0 讨论(0)
  • 2021-02-14 05:21

    If you use a backgroundworker to start the second thread and use the ProgressChanged event to notify the other thread that data is ready. Other events are available as well. THis MSDN article should get you started.

    0 讨论(0)
  • 2021-02-14 05:22

    You can use an AutoResetEvent (or ManualResetEvent). If you use AutoResetEvent.WaitOne(0, false), it will not block. For example:

    AutoResetEvent ev = new AutoResetEvent(false);
    ...
    if(ev.WaitOne(0, false)) {
      // event happened
    }
    else {
     // do other stuff
    }
    
    0 讨论(0)
  • 2021-02-14 05:32

    There are many ways to do this, depending upon exactly what you want to do. A producer/consumer queue is probably what you want. For an excellent in-depth look into threads, see the chapter on Threading (available online) from the excellent book C# 3.0 in a Nutshell.

    0 讨论(0)
提交回复
热议问题