[英]killing a thread from within in a form
我的应用程序调用Crystal Reports Viewer来显示报告。 我在单独的线程中运行报表查看器。 它工作正常。 它会正确显示报告。 我的问题是,如果运行时间太长,我想在处理报告时将其终止。 在报表处理期间,忙碌指示器在旋转,并且似乎阻止了报表查看器表单上的任何UI。 我的报表查看器表单上有一个水晶报表查看器,并在表单本身底部带有一个关闭按钮。 我希望能够单击关闭按钮并使其停止处理。 这是我的代码,用于在单个单元线程中运行查看器
public void RunReportStep1(UAReport report)
{
UAReportService service = new UAReportService(report);
service.RunReport();
var reportDocument = service.ReportDocument;
Thread staThread = new Thread(r => { RunReportStep2((ReportDocument) r); });
staThread.SetApartmentState(ApartmentState.STA);
staThread.Start(reportDocument);
staThread.Join();
}
public void RunReportStep2(ReportDocument reportDocument)
{
ReportViewerForm form = new ReportViewerForm(reportDocument);
form.BringToFront();
form.ShowDialog();
if (form.DialogResult == DialogResult.OK)
{
}
处理正在进行时,从报表查看器表单中杀死线程的最佳方法是什么? 一旦处理完成并且报告被销毁,关闭报告就没有问题了。 在显示报告之前进行处理只是一个问题。 在报表处理过程中,关闭按钮没有响应。 有时,如果我反复单击它,我会得到答复,并且报告会取消。 但这并不一致,我必须反复单击它。 这对我的客户来说是不可接受的。
从另一个线程调用service.RunReport(),然后等待该线程结束或经过一定时间。 我没有为此编写所有代码,但是至少没有描述任何我未编写的代码。
// Global so it can be reached from both threads
UAReportService service;
// Global variable that is written to when the report doc is ready:
ReportDocType reportDoc; //Can't use var here unfortunately
public void RunReportStep1(UAReport report)
{
service = new UAReportService(report);
Thread staThread = new Thread(r => { RunReportStep2((UAReportService)r); });
staThread.SetApartmentState(ApartmentState.STA);
staThread.Start(service);
// Save time the thread started:
DateTime start = DateTime.Now;
// Display a loading box (label or something, up to you).
// Then this function will end and your user can do stuff in the UI again (like press Cancel).
myLoadingBox.Visible = true;
}
public void RunReportStep2(UAReportService service)
{
service.RunReport();
reportDocument = service.ReportDocument;
}
// Call this new function periodically to see if the service thread finished, maybe once every second.
public checkAndDisplay()
{
// If thread is finished or 30 seconds have passed.
if (staThread.IsAlive == false || (DateTime.Now - start).TotalSeconds > 30)
{
// Show a message saying report failed to run
}
else // Else you can now show your report viewer
{
ReportViewerForm form = new ReportViewerForm(reportDocument);
form.BringToFront();
form.ShowDialog();
if (form.DialogResult == DialogResult.OK)
{
}
}
}
// Code for cancelling the report service call if user presses cancel button.
private void CancelButton_Click(object sender, EventArgs e)
{
// Terminate the report service thread.
staThread.Abort();
// Abort() isn't the nicest way to do this so if you can set a timeout on the UAReportService object (where it quits running after so long) that would be better.
// Or have it periodically check a variable to see if it should quit (see link below)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.