我的应用程序调用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)
{
}
在处理过程中从报表查看器表单中删除线程的最佳方法是什么。一旦处理完成并且报告被销毁,关闭报告就没问题了。在显示报告之前进行处理时,这只是一个问题。在处理报告时,关闭按钮没有响应。有时,如果我反复点击它,我可以得到回复,报告取消。但它不一致,我必须反复点击它。这是我的客户不能接受的。
答案 0 :(得分:0)
从另一个线程调用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)
}