问题:
我是c#的初学者,我在理解线程如何与表单一起工作时遇到了一些麻烦。当我的程序点击关键点时,我试图更新进度条,而我无法在此处使用它是我的代码。
对于我的"工人" class:
public void addFollower(string followerName, Action<string> followerAction) {
this.followers.Add(followerName, followerAction);
}
private void notifyFollowers(string message) {
if (followers.Count > 0) {
foreach (String followerName in followers.Keys) {
followers[followerName].Invoke(message);
}
}
}
我的链接类(控制器可能?):
public void runWithParams(Dictionary<string,string> parameters, Action<string> updateManager = null){
string app = parameters["appName"];
string navigator = parameters["navigatorName"];
string mode = parameters["mode"];
string scenario = parameters["scenarioName"];
try {
Scenario sc = this.scenarioBuilders[app].buildScenario(scenario);
if(updateManager != null) sc.addFollower("updateManager", updateManager);
Thread TestRunner = new Thread(sc.run);
TestRunner.Start();
} catch (Exception ex) {
Console.WriteLine(ex.Message);
Console.WriteLine("Unexpected shutdown or driver unreachable");
}
}
对于gui:
private void ButtonRun_Click(object sender, EventArgs e) {
Dictionary<string, string> parameters = new Dictionary<string, string>{
{"appName",this.CBApplicationChoice.SelectedItem.ToString()},
{"navigatorName",this.CBNavigatorChoice.SelectedItem.ToString()},
{"mode",this.CBModeChoice.SelectedItem.ToString()},
{"scenarioName",this.CBScenarioChoice.SelectedItem.ToString()}
};
this.dispatcher.runWithParams(parameters, ManageRealTimeStep1);
}
public void ManageRealTimeStep1(string liveevent){
if (liveevent.Contains("NumberOfPages")) {
this.PBStep1.Maximum = Convert.ToInt32(liveevent.Split(':')[1]);
} else if (liveevent.Contains("StartingTestNewPage")) {
this.PBStep1.Increment(1);
}
}
当我点击RunButton时,我收到了InvalidOperationException,错误显示我试图调用另一个线程中的函数。我该如何解决?
提前感谢您的任何答案/见解
解决方案:
我在gui中更改了方法:
public void ManageRealTimeStep1(string liveevent) {
BeginInvoke(new Action(() => {
if (liveevent.Contains("NumberOfPages")) {
this.PBStep1.Maximum = Convert.ToInt32(liveevent.Split(':')[1]);
} else if (liveevent.Contains("StartingTestNewPage")) {
this.PBStep1.Increment(1);
}
}));
}
答案 0 :(得分:1)
使用BeginInvoke
方法:
BeginInvoke(new Action(() =>
{
this.PBStep1.Maximum = Convert.ToInt32(liveevent.Split(':')[1]);
}));
阅读有关从另一个线程here
更新WinForms UI的更多信息答案 1 :(得分:0)
不允许您从其他主题更新GUI,请参阅How to update the GUI from another thread in C#?。
您正在使用ManageRealTimeStep1
方法访问GUI,该方法由后台线程上的Scenario
类(作为回调)使用。