2013-05-15 34 views
0

我有一個應用程序,用戶可以啓動任務,繁重的任務。我想在一個用戶界面Grid中管理這些任務的進度(每行是一個任務,帶有進度條),用戶可以通過單擊按鈕(使用主線程)來顯示這個網格。我的問題是十字線操作。我知道爲什麼:每當任務進程改變(使用thread1)時,該算法嘗試更新網格數據源(使用主線程)。但我不知道如何解決它。在一個用戶界面中管理任務進度

我的網格的DataSource屬性設置爲BindingList<BackgroundOperation>

我的任務的定義(BackgroundOperation)

public class BackgroundOperation 
{ 
    public int progression; 
    public int Progression 
    { 
     get { return progression;} 
     set 
     { 
      progression = value; 
      OnPropertyChanged("Progression"); 
     } 
    } 

    public event EventHandler OnRun; 
    public event EventHandler<ProgressChangedEventArgs> OnProgressChanged; 
    public event PropertyChangedEventHandler PropertyChanged; 

    public void Run() 
    { 
     var task = new Task(() => 
     { 
      if (OnRun != null) 
       OnRun(this, null); 
     }); 

    task.Start(); 
    } 

    public void ReportProgress(int progression) 
    { 
     Progression = progression; 

     if (OnProgressChanged != null) 
      OnProgressChanged(this, new ProgressChangedEventArgs { Progression = progression }); 
    } 


    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 
} 
+0

你有訪問.NET4.0甚至.NET4.5 +?您在這裏沒有使用TPL,但我建議您這樣做... – MoonKnight

+1

您希望主線程和主線程僅用於處理UI。這意味着你必須找到一個方法讓thread1在給定的進程中發出變化信號,主要捕獲該信號並更新顯示。通常的技術是建立一個事件隊列,每個線程將產生/消耗的事件隊列。 – didierc

回答

2

你需要運行OnProgressChanged在UI線程(這BTW應該只是ProgressChanged調用)。你可以做到這一點通過保存the current SynchronizationContext創建類的時候,然後Post()荷蘭國際集團委託有:

public class BackgroundOperation 
{ 
    private readonly SynchronizationContext m_synchronizationContext; 

    public BackgroundOperation() 
    { 
     m_synchronizationContext = SynchronizationContext.Current; 
    } 

    … 

    public void ReportProgress(int progression) 
    { 
     Progression = progression; 

     var handler = OnProgressChanged; 
     if (handler != null) 
      m_synchronizationContext.Post(
       _ => handler(
        this, 
        new ProgressChangedEventArgs { Progression = progression }), 
       null); 
    } 
} 
+0

它的工作原理與它應該一樣。非常感謝您的幫助。 (對於SynchronizationContext類爲+1)。 – SidAhmed

相關問題