-1

我有一个 WinForm C# 应用程序,我正在以编程方式生成一个 pdf 文件并通过电子邮件发送它。我正在尝试显示一个显示状态(生成文件、发送、成功发送或失败)的状态标签。但它只显示最后一个状态(发送成功)。我应该怎么做才能显示状态更新?

我试过下面的代码。

try
  {                
      Status_Label.Invoke((MethodInvoker)(() => Status_Label.Text ="Generating PDF fie..."));

      /*
      GENERATING CODE TO CREATE PDF FILE
      */

      Status_Label.Invoke((MethodInvoker)(() => Status_Label.Text = "Sending Email..."));

       /*
      GENERATING CODE for sending the Email
      */

      Status_Label.Invoke((MethodInvoker)(() => Status_Label.Text = "Sent successfully."));


  }
  catch (Exception ex)
  {  
       Status_Label.Invoke((MethodInvoker)(() => Status_Label.Text = "Sending failed."));
  }
4

4 回答 4

3

你这样做是不对的。你应该使用这样BackgroundWorker的东西。它在单独的线程上运行,但可以将进度发布到调用线程(通常是 UI 线程)。

于 2013-07-24T07:04:34.217 回答
1

那是因为 GUI 线程正在做所有的工作,当它卡在你的方法中时,GUI 不会得到更新。使用命令进行 GUI 更新也不行。因此,您必须将 PDF 生成和电子邮件发送放到自己的线程中。我会在 GUI 线程中激活一个计时器,该计时器读取一个(同步的!)队列,该队列正在由您的新线程填充。如果队列中有一个新元素,则用其内容填充标签,直到线程终止,此时停止计时器。

于 2013-07-24T07:00:09.197 回答
1

您应该使用 BackgroundWorker 来生成 PDF 文件并使用 ProgressChanged 事件和 ReportProgress 函数来更新您的状态标签。

于 2013-07-24T07:27:06.510 回答
0

除了标签,你的问题没有提到多线程。您目前是否在您的 UI 线程中执行所有这一代?(即作为一些注册事件的直接结果,例如按钮单击。)如果是这样,问题是您的所有代码在 UI 再次更新之前执行。

如果这只在一个线程运行,只需更改Status_Label.Text然后调用Application.DoEvents(). 这将强制应用程序处理任何其他排队的 UI 事件,并返回到您的函数。

于 2013-07-24T07:05:36.423 回答