我已经为一个问题做了6个小时了,我还是想不出答案。我希望你能帮我。
我正在从事一个与水晶报告引擎( .NET Framework4.0,32位C#应用程序上的最新版本)有关的项目。基本上,它是这样工作的:
我正在打开我的主表单,它动态地显示特定报告文件(.rpt)的所有参数。输入参数值后,应用程序将执行一些语法检查,并将参数传递给ReportDocument。
问题是:现在我正在创建一个新的ReportForm (我自己的类),它是一个带有CrystalReportViewer的Windows.Form派生类。该ReportForm将crystalReportViewer对象的ReportSource设置为先前创建的带有传递参数的ReportDocument。当窗体出现时,->水晶报表查看器正在加载。
问题1:在水晶报表查看器加载报表时,我仍然希望能够访问我的主表单(有时可能需要5-6分钟)--例如,在前一个报表仍在加载时创建一些其他报告。这只有在我为这个新表单创建一个线程时才有可能,但这(有时)会导致一个ContextSwitchDeadlock,因为我必须创建一个新的线程,它正在创建一个新的GUI-控件( ReportForm)。
问题2:如果我不创建一个新线程并启动新的ReportForm (例如使用myNewReportForm.Show() ),那么我必须等到报表加载之后才能访问我的主表单(直到报告完全加载)。下一个问题是,我无法关闭/退出/关闭我的应用程序,因为线程仍然在加载报告--我还必须等待,直到加载了报告。但是,我希望能够随时关闭应用程序(主窗体和所有ReportForms)。
基本上看上去是这样的(简写):
/* pass parameters to reportDocument */
ReportForm reportForm = new ReportForm(reportDocument);
reportForm.Show();在ReportForm中:
crystalReportViewer.ReportSource = this.reportDocument;你有什么想法吗?
最好的,塞伦斯
发布于 2014-08-14 14:35:43
问题终于解决了。所以这就是我的解决方案:
对于正在为水晶报表查看器创建新线程的每个人:小心!
以下是一个通用的解决方案:
/* 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;
}
}最好的,塞伦斯
发布于 2018-02-23 12:06:37
谢谢!这是我的决心!
只是为了简化上面的代码:
/* 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;
}
}https://stackoverflow.com/questions/25298438
复制相似问题