2011-03-08 40 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

相關問題