我有一个带子窗口的WPF应用程序。我正在对按钮单击(在后台工作程序中)进行数据库连接检查。该过程需要一些时间才能完成,如果用户通过单击关闭按钮关闭子窗口,则该窗口将关闭,但后台工作程序将继续运行并在某段时间后显示该消息。
以下是示例代码:
BackgroundWorker worker;
private void Button_Click(object sender, RoutedEventArgs e)
{
worker = new BackgroundWorker();
worker.WorkerSupportsCancellation = true;
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
bsyInd.IsBusy = true;
worker.RunWorkerAsync();
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
if (worker.CancellationPending)
{
e.Cancel = true;
return;
}
// checking database connectivity
string connstring=myconnstring;
SqlConnection con=new SqlConnection(connstring);
con.Open();
if(con.State==ConnectionState.Open)
e.Result=true;
}
catch (Exception)
{
e.Result=false;
}
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
bool canConnect=(bool)e.Result;
if(canConnect)
MessageBox.Show("Connected");
else
MessageBox.Show("Failed");
bsyInd.IsBusy = false;
}
//close child window
private void ChildWindow_CloseButton_Click(object sender, RoutedEventArgs e)
{
//cancel the running process
worker.CancelAsync();
}
我在网上找到的所有解决方案都显示了在Do_Work内循环内连续监视/轮询后台工作者的CancellationPending属性的示例。在这里,我打算做的过程不需要任何循环,如何监视子窗口关闭按钮单击事件上的CancellationPending状态并取消后台进程?
提前致谢。
答案 0 :(得分:1)
如果有办法中止对SqlConnection.Open
的阻塞调用,您可以简单地将SqlConnection
对象声明为类中的成员变量,并在关闭按钮处理程序中执行中止调用。 / p>
private SqlConnection con;
private void ChildWindow_CloseButton_Click(object sender, RoutedEventArgs e)
{
if (con != null)
{
con.Dispose(); // or whatever would abort Open()
con = null;
}
}
在工作线程中Open
可能会抛出一种Aborted异常,你可以捕获然后设置e.Cancel = true;
。
答案 1 :(得分:0)
Dennis,您可以使用AutoResetEvent方法,请参阅AutoResetEvent Class
您向发生sql连接的线程发出信号,表明资源可以被释放。
您仍在使用单独的线程,因此不应阻止任何内容,但现在可以在线程之间进行通信,并特别通知其中一个线程释放资源。如果不是预期的格式,请道歉。
该链接有一个如何使用AutoResetEvent的示例。