Reputation: 79
Question :
I'm a beginner in c# and i'm having a bit of trouble to understand how thread works with a form. I'm trying to update a progressbar when my program hit keypoints and i can't get it to work here is my code.
For my "worker" 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);
}
}
}
for my linking class (controller maybe?) :
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");
}
}
For the 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);
}
}
I'm getting an InvalidOperationException when i click on the RunButton and the error says that i'm trying to call a function that is in another thread. How can i fix it?
Thanks in advance for any answer/ insights
Solution :
I changed the method in gui for :
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);
}
}));
}
Upvotes: 0
Views: 52
Reputation: 9571
You are not allowed to update the GUI from a different thread, see How to update the GUI from another thread in C#?.
You are accessing the GUI from the ManageRealTimeStep1
method which is used by the Scenario
class (as a callback) on the background thread.
Upvotes: 0
Reputation: 6293
Use BeginInvoke
method:
BeginInvoke(new Action(() =>
{
this.PBStep1.Maximum = Convert.ToInt32(liveevent.Split(':')[1]);
}));
Read more about updating WinForms UI from another thread here
Upvotes: 1