c#在运行线程时使用GUI中的操作

时间:2015-07-16 12:28:45

标签: c# multithreading winforms

问题:

我是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);
            }
        }));
}

2 个答案:

答案 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类(作为回调)使用。

相关问题