C# BeginInvoke出现问题(委托不执行任何操作)
希望你很好 我在BeginInvoke方面遇到了一个奇怪的问题,我真的需要你的帮助 我有一个类Reporting,它包含Report类型的多个实例C# BeginInvoke出现问题(委托不执行任何操作),c#,invoke,begininvoke,C#,Invoke,Begininvoke,希望你很好 我在BeginInvoke方面遇到了一个奇怪的问题,我真的需要你的帮助 我有一个类Reporting,它包含Report类型的多个实例 Class Reporting : UserControl { //Reports are inherited from UserControl Report _report1; Report _report2; Report _report3; //Instanciate and return the Report corre
Class Reporting : UserControl
{
//Reports are inherited from UserControl
Report _report1;
Report _report2;
Report _report3;
//Instanciate and return the Report corresponding to the passed ID (The report is
//instanciated and created only if it's null)
public Report GetReport(int reportId);
public delegate void GenerateReportAsImageDelegate(int reportId,string path)
//Generate the report and save it as image
public void GenerateReportAsImage(int reportId,string path)
{
if(InvokeRequired)
{
BeginInvoke(new GenerateReportAsImageDelegate(GenerateReportAsImage),new object[]{reportId,path});
}
else
{
//... Generating the report etc..
}
}
....
}
它是一个以表单形式显示的用户控件,同样的用户控件也从Windows服务中用于每分钟生成报告(并保存为图像)
为了每分钟生成一份报告,我使用System.Threading.Timer
下面是我的类在服务中生成报告的样子:
class ReportServiceClass
{
Reporting _reportingObject;
System.Threading.Timer _timer;
Public ReportingServiceClass(int reportId)
{
_timer = new Timer(new TimerCallback(this.CreateReport), reportId, 0, 1000)
}
private void CreateReport(Object stateInfo)
{
int reportId = Convert.ToInt32(stateInfo);
//To ensure that the _reportingObject is created on the same thread as the report
if(_reportingObject == null)
_reportingObject = new _reportingObject();
_reportingObject.GenerateReportAsImage(reportId,@"c:\reports\report.PNG")
}
}
几乎一切都很顺利。。有时CreateReport会在线程池的另一个线程中执行。因此,当我对报表及其组件(已在其他线程中创建)执行某些操作时,invokererequired设置为true,这是非常明显的。。。但是BeginInvoke不会执行任何操作!这几乎就像创建报告的线程不再存在
你们有办法避免这个问题吗
现在我面对这个问题已经一个星期了,我已经在谷歌上搜索过了。但是什么都没有
非常感谢 我认为您使用了错误的调用,请尝试以下操作:
if(this.InvokeRequired)
{
this.Invoke(new Action<int,string>(GenerateReportAsImage), reportId, path);
}
else
...
if(this.invokererequired)
{
调用(新操作(GenerateReportAsImage)、报告ID、路径);
}
其他的
...
以下内容来自ThreadPool.SetMinThreads文档:
空闲线程由线程池维护,以减少满足线程池线程请求所需的时间。工作线程和异步I/O线程分别保持最小值。超过最小值的空闲线程将被终止,以节省系统资源。空闲线程的维护是一项后台任务
另外,我的理解是BeginInvoke和Invoke依赖WinForms“消息泵”来实际调用代码。我从来没有听说过在服务中使用它们——看起来这种机制是为一个真正的WinForms应用程序设计的,它有一个可见的UI和一个消息泵。让它在服务中可靠地工作可能是可能的,但看起来您至少应该创建自己的线程,而不是为创建UserControl并管理调用的线程使用线程池
您可能希望也可能不希望使用Invoke而不是BeginInvoke。前者是同步的,后者是异步的。我没有明确使用线程池,但我的TimerCallBack是在线程池中启动的。我不知道我必须关注什么问题:-我必须确保TimerCallBack始终在同一线程中启动,还是-我必须不使用BeginInvoke(因为此机制是为真正的Windows窗体设计的)当CreateReport在不同于创建报表的线程上执行时,寻找在报表上执行任务的其他方法。