2016-10-25 90 views
0

我正在使用Cplex DLL進行優化操作的C#.Net應用程序,並且在該操作期間,我想將狀態進度寫入啓動操作的狀態欄。從cplex回調函數的窗體上訪問狀態欄c#

這是具體表格的總體佈局;

namespace ActResMain 
{ 
    public class FormOptimize : System.Windows.Forms.Form 
    { 
     private callCplex() 
     { 
      //... 
      cplex.Use(new Cplex_ContinuousCallback()); 
      cplex.Solve() 
     } 
     public void Update_OptimizeStatusbarPanel(String strText) 
     { 
       statusBarPanel_1.Text = strText; 
       statusBar1.Refresh(); 
     } 
     internal class Cplex_ContinuousCallback : Cplex.ContinuousCallback 
     { 
      FormOptimize formOpt = new FormOptimize(); 
      public override void Main() 
      { 
       //From here I want to edit the statusbar at FormOptimize. I can write progress to console without any problems, but cannot reach function "Update_OptimizeStatusbarPanel". 
       //If I include "FormOptimize formOpt = new FormOptimize" here, i get Visual studio exception on illegal window reference. 
      } 
     } 

    } 
} 

我自己也嘗試調用這樣的Update_OptimizeStatusbarPanel功能:

internal class Cplex_ContinuousCallback : Cplex.ContinuousCallback 
      { 
       FormOptimize formOpt = new FormOptimize(); 
       public override void Main() 
       { 
        FormCollection fc = Application.OpenForms; 
        var mpc = fc[1]; 
        Type type = mpc.GetType(); 
        MethodInfo dynMethod = type.GetMethod("Update_OptimizeStatusbarPanel"); 
        dynMethod.Invoke(mpc, new object[] { String.Format("Running Optimization: {0} iterations ", Niterations)}); 
       } 
      } 

但後來我從Visual Studio中指出,由一個線程創建的對象不能從另一個線程修改一個例外。

也許這是愚蠢的東西,我已經錯過了,但幫助是極大的appriciated

編輯:我編輯的代碼,每穆罕默德Dehghans建議,

public class FormOptimize : System.Windows.Forms.Form 
{ 
    private callCplex() 
    { 
     cplex.Use(new Cplex_ContinuousCallback(this)); 
     cplex.Solve() 
    } 

    internal class Cplex_ContinuousCallback : Cplex.ContinuousCallback 
    { 
     FormOptimize _formOptimize; 
     public Cplex_ContinuousCallback(FormOptimize formOptimize) 
     { 
      this._formOptimize = formOptimize; 
     } 

     public override void Main() 
     { 
      if (Niterations % 10 == 0) 
      { 
       _formOptimize.Update_OptimizeStatusbarPanel(0, String.Format("Running Optimization: {0} iterations ", Niterations), 0); 
      } 
     } 
    } 

    public void Update_OptimizeStatusbarPanel(short panelIndex, String strText, short severity) 
    { 
     if (statusBar1.InvokeRequired) 
      statusBar1.Invoke(new Action<short, string, short>(Update_OptimizeStatusbarPanel), panelIndex, strText, severity); 
     else 
     { 
      if (panelIndex == 0) 
      { 
       //... 
       statusBarPanel_0.Text = strText; 
      } 
      else if (panelIndex == 1) 
      { 
       //... 
       statusBarPanel_1.Text = strText; 

      } 
      statusBar1.Refresh(); 
     } 
    } 
} 

但是這樣做,我顯然打破了東西,因爲應用程序只是在第一次調用statusBar1.Invoke()之後停止。如果我暫停調試器,它說cplex.Solve()正在執行,但是沒有更多的事情發生。

回答

0

首先,您需要將表單實例傳遞給實現的回調類,因此當調用Main方法時,您可以訪問屏幕上顯示的確切實例。其次,你需要使用Invoke方法來更新另一個線程的UI控件(我到目前爲止還沒有和CPLEX一起工作過,但是我猜這個回調是從另一個線程調用的,這很平常)。 Read this for more information.

完整的代碼可能是:

public class FormOptimize : System.Windows.Forms.Form 
{ 
    private callCplex() 
    { 
     //Misc code 
     cplex.Use(new Cplex_ContinuousCallback(this)); // <-- passing `this` 
     cplex.Solve() 
     //Misc code 
    } 

    public void Update_OptimizeStatusbarPanel(String strText) 
    { 
     if (statusBarPanel_1.InvokeRequired) 
      statusBarPanel_1.Invoke(Action<string>(Update_OptimizeStatusbarPanel), strText); 
     else 
     { 
      statusBarPanel_1.Text = strText; 
      statusBar1.Refresh(); 
     } 
    } 

    internal class Cplex_ContinuousCallback : Cplex.ContinuousCallback 
    { 
     FormOptimize _formOptimize; 
     public Cplex_ContinuousCallback(FormOptimize formOptimize) 
     { 
      this._formOptimize = formOptimize; 
     } 

     public override void Main() 
     { 
      //... 
      _formOptimize.Update_OptimizeStatusbarPanel(String.Format("Running Optimization: {0} iterations ", Niterations)); 
     } 
    } 
} 
+0

好像它既解決了這個問題,並創造了一個又一個。現在應用程序似乎在調用statusbar1後停止了一些事情。調用我更新了我的問題,並解釋了您的答案。實施了不正確的事情 –