【发布时间】:2016-10-25 09:50:50
【问题描述】:
我正在使用 C# .Net 应用程序,该应用程序使用 Cplex DLL 进行优化操作,并且在该操作期间,我想将状态进度写入启动操作的状态栏。
这是具体表格的大体布局;
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 得到一个异常,指出一个线程创建的对象不能从另一个线程修改。
也许这是我错过的一些愚蠢的事情,但非常感谢您的帮助
编辑:我根据 Mohammad 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() 之后 ..stops 。如果我暂停调试器,它会说 cplex.Solve() 正在执行,但没有任何反应。
【问题讨论】: