2011-03-08 57 views
3

在我的应用程序中,我发送更大尺寸(> 2.5 Mb)的电子邮件。现在直到电子邮件正在发送,应用程序处于挂起状态(鼠标光标处于忙状态)。当使用后台工作进程时,Windows应用程序被吊死

我的一个朋友建议使用后台工作,“可以”显示消息,如“请稍候...发送电子邮件”。我不知道如何使用后台工作进程。请指引我

或者,如果有任何其他的更快/更简便的方法,我将不胜感激投入

+0

您是否使用ASP.NET或的WinForms? (您的问题有两个标签。)它有所不同,因为BackgroundWorker通常不适合Web应用程序。 – Heinzi 2011-03-08 17:20:28

+0

你是否在这里搜索背景工作者?还有其他几个与使用它们有关的问题。其中一个可能会提供解决方案。 – 2011-03-08 17:20:55

回答

0

如果您不希望您的UI挂在等待一个漫长的过程,你到使用一个线程。 BackgroundWorker是一个很好的实现这一点,提供了钩子供你使用报告进度,允许用户中止进程等

有很多关于这里堆栈溢出BackgroundWorker疑问或检查MSDN documentation

+0

我指的是MSDN文档并在我的电脑上复制了第一个示例代码。我没有收到CancellationPending和Reportprogress。我错过了任何参考?仅供参考,我添加了System.Threading,System.Windows.Forms和System.ComponentModel。 – 2011-03-08 19:55:00

+0

@Xor - 为“backgroundworker”搜索堆栈溢出(或使用谷歌网站:stackoverflow)。关于这个话题有很多问题。如果您在发布代码时遇到问题,则将**作为新问题**并解释不起作用。不过,我相信你所需要的所有信息已经在那里了。 – ChrisF 2011-03-08 19:57:49

+0

感谢您的及时回复 – 2011-03-08 19:59:14

2

你不想使用单独的过程 - 要使用不同的线程

发送电子邮件的工作不应该在UI线程中完成,因为这会阻止它更新。但是,可能想要在发送电子邮件时禁用部分UI,具体取决于您的应用程序。

当涉及到在后台执行电子邮件工作时,可以显式创建新线程,使用线程池或创建BackgroundWorker。您可能想要在发送电子邮件时使用Control.InvokeControl.BeginInvoke将委托调用编组回给UI线程。就我个人而言,我可能会直接使用一个线程 - 这听起来像需要一段合理的时间,我的猜测是,你将无法报告有意义的进度(这是BackgroundWorker变得容易的主要任务)。编辑:根据评论,BackgroundWorker也编组UIs线程的异常,你可能会发现有用的。

因此,像:

public void SendEmailButtonClicked(object sender, EventArgs e) 
{ 
    // Make any changes to the UI here to disable whatever you want 
    new Thread(SendEmail).Start(); 
} 

private void SendEmail() 
{ 
    // Do the sending of the email here (this is in the non-UI thread) 

    // Then afterwards, possibly in a finally block 
    Action action = EmailSent; 
    this.BeginInvoke(action); 
} 

private void EmailSent() 
{ 
    // Back in the UI thread, do whatever you need to indicate 
    // success/failure, re-enable disabled parts of the UI etc 
} 
+0

发送电子邮件不在后台完成。事实上这很好,如果电子邮件是在'眼睛的前面'。当我点击“发送”按钮时,会发生什么情况,因为发送附件大于2.5 Mb需要时间... – 2011-03-08 17:51:24

+0

@Xor:就UI线程而言,它是在后台完成的。通过所有的手段禁用其余的用户界面,并建立一个进度条或类似的东西,但你*不希望在UI线程中做到这一点。 – 2011-03-08 18:13:57

+1

使用'BackgroundWorker'类有一个额外的好处:异常被捕获并传递给UI线程(在'RunWorkerCompleted'事件中)。对于“手动”线程,在后台线程中需要某种捕获所有异常处理,否则只是在发生异常时停止并无提示地失败。 – Heinzi 2011-03-08 18:24:47

0
+0

感谢您的链接。我试图从第二个链接开发演示(而不是复制)的应用程序,但我没有得到 _bw.DoWork + = bw_DoWork;在第一个例子中。我错过了什么吗? – 2011-03-08 17:59:45

+0

'_bw.DoWork + = bw_DoWork','bw_DoWork'处理程序将被注册到bw的'DoWork'事件。 – Kumar 2011-03-08 18:08:03

相关问题