2015-12-18 84 views
1

今天我正在重構Visual Studio擴展項目中的一些代碼(對於2013年),我遇到了一些奇怪的事情。視覺工作室擴展,後臺工作人員和用戶界面

在代碼中有一個執行持久任務的後臺工作人員。裏面的dowork事件代碼那裏調用Visual Studio的UI組件。令我驚訝的是,這些代碼毫無例外地執行當我認爲UI更新只能在progresschangeddoworkcomplete事件中完成時,我過時了嗎?

驚訝,因爲我是我試圖執行一個Visual Studio中下面的代碼(2013年)擴建項目:

private void StartAJob() 
     { 
      BackgroundWorker bgWork = new BackgroundWorker(); 
      bgWork.DoWork += Work; 
      bgWork.RunWorkerAsync(); 

     } 

     private void Work(object sender, DoWorkEventArgs e) 
     { 
      var statusBar = (IVsStatusbar)GetService(typeof(SVsStatusbar)); 
      statusBar.Progress(1, 1, "Starting a job...", 0, 2); 
      //do something that that takes a while 
      statusBar.Progress(1, 1, "A little longer...", 1, 2); 
      //do something else 
      statusBar.Progress(1, 1, "Done!", 2, 2); 
      MessageBox.Show("yay?"); 
     } 

這是否意味着我可以savely執行接口代碼在DoWork的事件現在(他們總是告訴我不)。或者,這是一些視覺工作室的魔力,可以解決遠離我的代碼的異常。

+3

只是猜測,但可能是VS組件被寫入來檢查是否需要同步調用d到UI線程(例如就像你會用'InvokeRequired'查詢) –

+1

同意以前的評論。很可能有同步代碼。這不是唯一的 - 例如,WPF綁定可以爲您做同步。 – Dennis

+0

@ZdeslavVojkovic我認爲這將是沿着這些路線。但我無法找到任何支持它的理論。 –

回答

-1

你可以使用背景工人中的接口,但是你應該檢查

InvokeRequired

當你從後臺工作接觸任何UI,因爲它可以在運行分開線程到UI線程。例如:

delegate void ProgressMessageCallback(string message); 

    private void ProgressMessage(string message) 
    { 
     if (InvokeRequired) 
     { 
      ProgressMessageCallback d = new ProgressMessageCallback(ProgressMessage); 
      this.Invoke(d, new object[] { message }); 
     } 
     else 
     { 
      this.lblProgressMessage.Text = message; 
     } 
    } 
+0

'InvokeRequired'在這裏沒有幫助。 OP調用VS自動化接口,而不是winforms控件。 – Dennis

+0

我知道這一點,通常我會使用progresschanged和doworkcomplete事件來更新界面。然而現在它似乎在dowork活動中工作,我很好奇爲什麼。 –