线程控制台应用程序,无需使用AutoResetEvent,ManualResetEvent或Thread.Sleep

时间:2015-12-15 15:15:32

标签: c# multithreading

我正在创建一个可以进行大量数据库处理的控制台应用程序。

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

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

我正在思考这些问题:

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块中;只是让代码很容易在这里显示。

问题在于我知道AutoResetEventManualResetEventThread.Sleep工具都是阻塞例程 - 这意味着我的数据库调用在此期间不会被处理。 / p>

我不想那样。

如何在保持控制台窗口打开的同时编写一些内容让数据库处理继续进行?

1 个答案:

答案 0 :(得分:3)

  

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

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

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

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