2012-10-18 116 views
1

我想在運行耗時任務時顯示一個簡單的WPF窗口,其中包含Indeterminate="True"進度條。在單獨線程中顯示WPF ProgressBar窗口

我已經在this示例之後實施了我的解決方案 - Reed Copsey。

一旦過程完成,我需要關閉窗口。 我的猜測是,要實現這一點,我要麼殺死線程或關閉視圖(窗口)。

不幸的是這兩種方式給我下面的錯誤:

1)上調用線程Abort()

窗口關閉,這是正確的,但我還是發現了以下錯誤:

無法評估表達式,因爲代碼被優化或天然幀是在調用堆棧的頂部

2)View.Close()

調用線程不能訪問此對象,因爲不同的線程擁有它。

所需的邏輯需要在StopThread()方法來實現,任何想法我可以做優雅關閉窗口:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Diagnostics; 
using System.Threading; 
using Microsoft.Practices.Composite.Presentation.Commands; 

namespace ProgressBar 
{ 
    public class ProgressBarViewModel 
    { 
     public DelegateCommand<object> CloseCommand { get; set; } 
     Thread newWindowThread; 

     string _closeButton; 
     public string CloseButton 
     { 
      get { return _closeButton; } 
      set { _closeButton = value; } 
     } 

     ProgressBarView _view; 
     public ProgressBarView View 
     { 
      get { return _view; } 
      set { _view = value; } 
     } 

     public ProgressBarViewModel(ProgressBarView view) 
     { 
       CloseButton = "Close"; 
       CloseCommand = new DelegateCommand<object>(CloseForm); 

       View = view; 
       View.Closing +=new System.ComponentModel.CancelEventHandler(View_Closing); 
       View.DataContext = this; 
     } 

     public void View_Closing(object sender,CancelEventArgs e) 
     { 
      StopThread(); 
     } 

     public void CloseForm(object p) 
     { 
      StopThread(); 
     } 

     private void StopThread() 
     { 
      try 
      { 
       //View.Close(); 
       newWindowThread.Abort(); 
      } 
      catch (Exception eX) 
      { 
       Debugger.Break(); 
       //Getting an error when attempting to end the thread: 
       //Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack 
      } 
     } 

     public void ShowProgress() 
     { 
       newWindowThread = new Thread(new ThreadStart(() => 
       { 
        ProgressBarView tempWindow = new ProgressBarView(); 
        tempWindow.DataContext = this; 
        tempWindow.Show(); 
        System.Windows.Threading.Dispatcher.Run(); 
       })); 

       newWindowThread.SetApartmentState(ApartmentState.STA); 
       newWindowThread.IsBackground = true; 
       newWindowThread.Start(); 
     } 
    } 
} 

回答

0

你應該做的是它自己的類中封裝了您的操作,使它在事件完成時引發事件(或者您想關閉視圖)

事件處理程序將需要使用Dispatcher在與視圖相同的線程中運行close()

+0

你能提供一個例子嗎?我是比較新的線程 –

0

也許你應該考慮使用BackgroundWorker進行此操作?您可以響應RunWorkerCompleted事件來關閉視圖。

public void YourFunction(Dispatcher dispatcher) 
{ 
    BackgroundWorker bw = new BackgroundWorker(); 
    bw.DoWork += (sender, args) => 
     { 
     ...do your long running operation 
     }; 

    bw.RunWorkerCompleted += (sender, args) => 
     { 
     dispatcher.BeginInvoke(...close your view here); 
     } 

    bw.RunWorkerAsync(); 
} 
+0

給了它一個鏡頭,當我嘗試調用View.Close();任何其他想法? –

+0

@Deni ...你是否正在調試發佈版本(「代碼已優化」)?這可能與Visual Studio有關。 –

+0

不,在調試模式下 –