简体   繁体   English

从C#中的另一个线程更新UI

[英]Updating UI from another thread in C#

I have a silly question which prevents me to proceed with my project. 我有一个愚蠢的问题阻止我继续我的项目。 My project involves multi-threading(foreground threads), so i would like to have all my threads kept in a different .cs file than Form1.cs. 我的项目涉及多线程(前台线程),所以我希望我的所有线程都保存在与Form1.cs不同的.cs文件中。

Is this a good call or i should write all my methods in the Form.cs? 这是一个很好的电话,还是我应该在Form.cs中写下我的所有方法? All the examples found on the net have the methods in the same class. 在网上找到的所有示例都具有相同类中的方法。

The problem that I am facing is: how to update my controls in the Form1. 我面临的问题是:如何在Form1中更新我的控件。 If i had put my methods in the Form class it would be easy, i would have used: 如果我把我的方法放在Form类中它会很容易,我会使用:

if(this.InvokeRequired)
this.Invoke((Action)(() => richTextBox.Text += (line + Environment.NewLine)));

but updating that control from another class it gives me a headache, knowing that i might miss something rather simple. 但是从另一个班级更新控制权让我头疼,知道我可能会错过一些相当简单的东西。

Is this a good call or i should write all my methods in the Form.cs? 这是一个很好的电话,还是我应该在Form.cs中写下我的所有方法?

There are lots of good reasons to separate the application logic from the GUI. 将应用程序逻辑与GUI分离有很多充分的理由。 For example, if you want to write two different applications that share some of the same logic then you can put this logic in its own class. 例如,如果要编写两个共享某些相同逻辑的不同应用程序,则可以将此逻辑放在自己的类中。 It also helps separate components by responsibility (calculation vs user interaction) which can make your design easier to understand and to test. 它还有助于按责任(计算与用户交互)分离组件,这可以使您的设计更容易理解和测试。 Your approach is reasonable, although it does mean you have a little more work to do. 你的方法是合理的,虽然它确实意味着你还有一些工作要做。

The problem that I am facing is: how to update my controls in the Form1. 我面临的问题是:如何在Form1中更新我的控件。

You can add events to your new class and fire them when you want to notify some progress or information. 您可以向新类添加事件,并在想要通知某些进度或信息时触发它们。 In your main form you can subscribe to these events and call the appropriate methods to update the GUI (remembering to call Invoke if needed). 在您的主窗体中,您可以订阅这些事件并调用适当的方法来更新GUI(如果需要,记住调用Invoke)。

Keep all UI manipulation in Form.cs like: 保持Form.cs中的所有UI操作,如:

public void UpdateText(string text)
{
    if (InvokeRequired) Invoke(() = UpdateText(text));
    else myLabel.Text = text;
}

In other classes just keep reference to your form, so you can call methods on in. 在其他类中,只需保持对表单的引用,这样就可以调用on方法。

The code to actually update the controls should be in your Form.cs file. 实际更新控件的代码应该在Form.cs文件中。 The exact way that you are performing the update will depend upon how you want to invoke the update. 执行更新的确切方式取决于您希望如何调用更新。 I'd recommend looking at the Model-View-Controller pattern . 我建议查看模型 - 视图 - 控制器模式 You want to separate you business logic for operations from your form but your form should encapsulate the controls and logic for updating those controls. 您希望将操作的业务逻辑与表单分开,但您的表单应封装用于更新这些控件的控件和逻辑。

i would like to have all my threads kept in a different .cs file than Form1.cs. 我希望我的所有线程都保存在与Form1.cs不同的.cs文件中。

This statement is somewhat inaccurate as threads simply have execution contexts, which can be code from your Form1.cs or any other class file. 这个语句有点不准确,因为线程只有执行上下文,可以是Form1.cs或任何其他类文件中的代码。 However, I always prefer to only have form logic/manipulation code in my forms. 但是,我总是喜欢在表单中只有表单逻辑/操作代码。 Any other code should be elsewhere. 任何其他代码应该在其他地方。 With that, your other classes should NOT know about your form - that produces unnecessary coupling. 有了这个,你的其他类不应该知道你的表单 - 这会产生不必要的耦合。

Use events or callbacks to invoke responses you want of your form. 使用事件或回调来调用您希望表单的响应。 Your form should then contain the code that invokes your UI manipulation code to run on the main UI thread. 然后,您的表单应包含调用UI操作代码以在主UI线程上运行的代码。

If your methods require updating the controls of the form, then of course go ahead and put them in the form class. 如果您的方法需要更新表单的控件,那么当然要继续将它们放在表单类中。 I am expecting this to be the case here. 我希望这是这种情况。

您也可以使用回调 ..因此您可以从UI中分离逻辑

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM