使用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窗口打开的同时编写一些内容来继续数据库处理?
问题是我知道AutoResetEventManualResetEvent和Thread.Sleep工具都是阻塞例程-这意味着在此期间不会处理我的数据库调用。
不,它们发生在DoWork回调中的另一个线程上:
worker.DoWork += delegate(object s, DoWorkEventArgs e)
因此,您放置在主线程中以防止控制台应用程序存在的mre.WaitOne(200)
不会阻止数据库操作。