繁体   English   中英

从表单中杀死线程

[英]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)
    }

优雅地关闭线程的MSDN示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM