C# BeginInvoke出现问题(委托不执行任何操作)

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

希望你很好

我在BeginInvoke方面遇到了一个奇怪的问题,我真的需要你的帮助

我有一个类Reporting,它包含Report类型的多个实例

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在不同于创建报表的线程上执行时,寻找在报表上执行任务的其他方法。