时间:2015-10-03 01:13:38

标签: c# multithreading crystal-reports

我的应用程序调用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)
        {

        }

在处理过程中从报表查看器表单中删除线程的最​​佳方法是什么。一旦处理完成并且报告被销毁,关闭报告就没问题了。在显示报告之前进行处理时,这只是一个问题。在处理报告时,关闭按钮没有响应。有时,如果我反复点击它,我可以得到回复,报告取消。但它不一致,我必须反复点击它。这是我的客户不能接受的。

1 个答案:

答案 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)
    }

MSDN example of gracefully closing a thread.