C#创建/关闭多个表单(线程) - Crystal Report Viewer

时间:2014-08-14 00:49:23

标签: c# multithreading forms crystal-reports report

我现在已经解决了6个小时的问题了,但我仍然无法弄明白。我希望你能帮助我。

我正在开发一个与Crystal-Report-Engine(SAP,.NET Framework 4.0上的最新版本,32位C#应用程序)有关的项目。基本上,它的工作原理如下:

我正在打开我的Main-Form,它动态地显示特定报告文件(.rpt)的所有参数。输入我的参数值后,应用程序正在进行一些语法检查并将参数传递给ReportDocument。

问题:现在我正在创建一个新的ReportForm(我自己的类),它是一个带有CrystalReportViewer的Windows.Form派生类。 ReportForm使用传递的参数将crystalReportViewer-Object的ReportSource设置为先前创建的ReportDocument。 - >当表单显示时,Crystal Report Viewer正在加载。

问题#1:我仍然希望能够在Crystal Report Viewer加载报告时访问我的主表单(有时这可能需要大约5-6分钟) - 例如,创建一些其他报告报告仍在加载中。这是唯一可能的,如果我为这个新表单创建一个线程 - 但是这(有时)会导致一个ContextSwitchDeadlock,因为我必须创建一个新的Thread,它正在创建一个新的GUI-Control(ReportForm)。

问题2:如果我没有创建新的Thread并以myNewReportForm.Show()为例启动新的ReportForm,那么我必须等到报告加载后才能访问我的Main-表格(直到报告完全加载)。下一个问题是我无法关闭/退出/杀死我的应用程序,因为线程仍在加载报告 - 我还必须等待,直到加载报告。但我想能够随时关闭应用程序(Main-Form AND所有ReportForms)

它基本上看起来像那样(短版):

/* pass parameters to reportDocument */
ReportForm reportForm = new ReportForm(reportDocument);
reportForm.Show();

在ReportForm中:

crystalReportViewer.ReportSource = this.reportDocument;

你有什么想法吗?

最佳, Cylence

2 个答案:

答案 0 :(得分:1)

终于解决了这个问题。所以这是我的解决方案:

为每个为Crystal Report Viewer创建新线程的人:小心!

Problem solving - SAP

以下是一般解决方案:

/* In Main Form */

            /*...*/

     ThreadStart threadStart = delegate() { reportThreadFunction(reportDocument); };
     Thread reportThread = new Thread(threadStart);

     /* Setting the ApartmentState to STA is very important! */
     reportThread.SetApartmentState(ApartmentState.STA);
     reportThread.Start();
}

         /* ... */

private void reportThreadFunction(ReportDocument reportDocument)
{
     ReportThread rt = new ReportThread(reportDocument);
     newReportForm = rt.Run();
     Application.Run(newReportForm);
     newReportForm.Show();
}


/* Class ReportThread */
public class ReportThread
{
    ReportDocument reportDocument;
    CrystalReportViewer crv;
    Template template;

    public ReportThread(ReportDocument reportDocument)
    {
        this.reportDocument = reportDocument;
    }

    public ReportForm Run()
    {
        ReportForm rf = new ReportForm(reportDocument);
        return rf;
    }
}

最佳, Cylence

答案 1 :(得分:0)

谢谢! 这个决心对我来说!

仅为简化上述代码:

 /* In Main Form */

 /*...*/
 ThreadStart threadStart = delegate({reportThreadFunction(reportDocument);};
 Thread reportThread = new Thread(threadStart);

 /* Setting the ApartmentState to STA is very important! */
 reportThread.SetApartmentState(ApartmentState.STA);
 reportThread.Start();
 }

 private void reportThreadFunction(ReportDocument reportDocument)
 {
     //Create and Start the form
     Application.Run(new ReportThread(reportDocument));
 } 


 /* Class ReportThread */
 /* A form whith a CrystalReportViewer inside*/
 public partial class ReportThread : Form
 {
     public CrystalReportViewer crv; //initiated in partial class off form

     public ReportThread(ReportDocument reportDocument)
     {
        InitializeComponent();
        CrystalReportViewer.ReportSource = reportDocument;
     }
 }