使用AutoResetEvent、ManualResetEvent或Thread.Sleep线程控制台应用程序而不阻塞

本文关键字:应用程序 控制台 线程 Sleep AutoResetEvent ManualResetEvent Thread 使用 | 更新日期: 2023-09-27 18:26:49

我正在创建一个控制台应用程序,它将执行大量数据库处理。

我使用BackgroundWorker控件进行数据库收集,并通过ProgressChanged事件写入控制台。

问题是,我需要一种方法在线程运行时保持控制台窗口打开,以便消息可以发布到它

我正沿着以下思路思考:

using (var worker = new BackgroundWorker())
{
    var mre = new ManualResetEvent(false);
    worker.WorkerReportsProgress = true;
    worker.WorkerSupportsCancellation = true;
    worker.DoWork += delegate(object s, DoWorkEventArgs e)
    // [SNIP] This code isn't related to the question
    worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs e)
    {
        Console.WriteLine(e.UserState.ToString());
    };
    worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs e)
    {
        mre.Set();
        // [SNIP] This code isn't related to the question
    }
    worker.RunWorkerAsync();
    Console.WriteLine("Import Started {0:G}", startTime);
    while (worker.IsBusy)
    {
        if (!mre.WaitOne(200))
        {
            mre.Reset();
        }
    }
}

注意:它不必在using块中;这使得代码在这里显示起来很容易。

问题是,我知道AutoResetEvent、ManualResetEvent和Thread.Sleep工具都是阻塞例程,这意味着在此期间我的数据库调用将不会得到处理。

我不想那样。

如何在保持Console窗口打开的同时编写一些内容来继续数据库处理?

使用AutoResetEvent、ManualResetEvent或Thread.Sleep线程控制台应用程序而不阻塞

问题是我知道AutoResetEventManualResetEvent和Thread.Sleep工具都是阻塞例程-这意味着在此期间不会处理我的数据库调用。

不,它们发生在DoWork回调中的另一个线程上:

worker.DoWork += delegate(object s, DoWorkEventArgs e)

因此,您放置在主线程中以防止控制台应用程序存在的mre.WaitOne(200)不会阻止数据库操作。