2013-01-15 62 views
1

我有一個WPF窗口,帶有一個產生BackgroundWorker線程來創建和發送電子郵件的按鈕。在此BackgroundWorker運行時,我想顯示一個用戶控件,顯示一些消息,後面跟着一個動畫「...」。該動畫由用戶控件中的計時器運行。當backgroundworker運行時計時器沒有被調用

即使我的郵件發送代碼位於BackgroundWorker上,用戶控件中的計時器也永遠不會被調用(當然,只有當Backgroundworker完成時,它纔會失敗)。

相關的代碼在WPF窗口:

public void Show() 
{ 
    tb_Message.Text = Message; 
    mTimer = new System.Timers.Timer(); 
    mTimer.Interval = Interval; 
    mTimer.Elapsed += new ElapsedEventHandler(mTimer_Elapsed); 
    mTimer.Start(); 
} 

void mTimer_Elapsed(object sender, ElapsedEventArgs e) 
{ 
    this.Dispatcher.Invoke((Action)(() => 
    { 

     int numPeriods = tb_Message.Text.Count(f => f == '.'); 
     if (numPeriods >= NumPeriods) 
     { 
      tb_Message.Text = Message; 
     } 
     else 
     { 
      tb_Message.Text += '.'; 
     }   
    })); 
} 

public void Hide() 
{ 
    mTimer.Stop(); 
} 

任何想法,爲什麼它鎖定了:

private void button_Send_Click(object sender, RoutedEventArgs e) 
{ 
    busyLabel.Show(); // this should start the animation timer inside the user control 

    BackgroundWorker worker = new BackgroundWorker(); 
    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); 
    worker.DoWork += new DoWorkEventHandler(worker_DoWork); 
    worker.RunWorkerAsync();  
} 

void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    this.Dispatcher.Invoke((Action)(() => 
    {  
     string body = textBox_Details.Text; 
     body += "User-added addtional information:" + textBox_AdditionalInfo.Text; 

     var smtp = new SmtpClient 
     { 
      ... 
     }; 

     using (var message = new MailMessage(fromAddress, toAddress) 
     { 
      Subject = subject, 
      Body = body 
     }) 
     { 
      smtp.Send(message); 
     } 
    })); 

} 

用戶控件( 「BusyLabel」)相關的代碼?

+0

您是否必須在UI線程上調用'worker_DoWork',因爲我沒有看到在那裏調用的任何UIElements,也許刪除'worker_DoWork'中的Dispatcher.Invoke將解決該問題。或將其更改爲'Dispatcher.BeginInvoke' –

+0

哎呀我砍了一些訪問UI的代碼。現在重新添加。 – akevan

回答

2

在您的worker_DoWork方法中使用Dispatcher.Invoke將執行回到UI線程,因此您不是異步執行該工作。

根據您顯示的代碼,您應該可以將其刪除。

如果在完成工作後需要顯示結果值,請將其放入DoWorkEventArgs,並且您將能夠在worker_RunWorkerCompleted處理程序的事件參數中訪問它(在UI線程上)。

使用BackgroundWorker的主要原因是編組是在封面下處理的,因此您不必使用Dispatcher.Invoke

+0

對不起,我忘了在上面包含一些UI訪問代碼。這就是爲什麼它使用Dispatcher.Invoke。我重新添加了它。 – akevan

+0

但是你指出了這個問題 - 「在你的worker_DoWork方法中使用Dispatcher.Invoke正在執行回UI界面線程」。我需要獲取UI線程上的UI元素,然後將它們作爲參數傳遞給BG工作者,從BG工作者中移除該Dispatcher,然後所有工作都很好。謝謝!! – akevan

相關問題