简体   繁体   English

执行与主线程并行的线程

[英]Execute threads parallel to the execution of the main thread

I have a form in C#, said form only has a multiline text box.我在 C# 中有一个表单,该表单只有一个多行文本框。

In the load method of this form I need to create 3 worker threads.在此表单的加载方法中,我需要创建 3 个工作线程。 These threads will call the Counter class where they will execute a method called count.这些线程将调用 Counter 类,它们将在其中执行一个名为 count 的方法。

This method is just a counter that will repeat the task 10000 times and its only task is to call a function in the Form main class which should print a message in the text box.这个方法只是一个计数器,它将重复任务 10000 次,它唯一的任务是调用 Form 主类中的一个函数,该函数应该在文本框中打印一条消息。

The message must be the number of the thread that executes the task and the number of the counter.消息必须是执行任务的线程号和计数器号。

It is supposed that with the invoke method this would be done in the main thread leaving the other threads working in the background, but what happens is that my form stays frozen and I don't understand why.假设使用invoke方法这将在主线程中完成,而其他线程在后台工作,但发生的是我的表单保持冻结状态,我不明白为什么。

I leave you my code, I hope you can help me.我把我的代码留给你,希望你能帮助我。

Form Main Class形成主类

namespace TestMultiHiloCSharp
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      Contador contadorClassOne = new(1, this);
      Contador contadorClassTwo = new(2, this);
      // Crea y arranca 2 hilos

      Task t1 = Task.Run(() => {
        contadorClassOne.contar();
      });

      Task t2 = Task.Run(() => {
        contadorClassTwo.contar();
      });
    }

    public void showMessage(String Mensaje)
    {
      this.Invoke(()=>
      {
        txtMultiLineTextBox.Text = Mensaje + "\r\n" + txtMultiLineTextBox.Text;
      });
    }
  }
}

Counter Class计数器类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestMultiHiloCSharp
{
  internal class Contador
  {
    int numHilo;
    Form1 thisForm;

    public Contador(int numHilo,Form1 thisForm)
    {
      this.numHilo = numHilo;
      this.thisForm = thisForm;
    }

    public void contar(){
      int cont = 0;
      while (cont < 100)
      {
        thisForm.showMessage("this is the theread: " + this.numHilo + " and the number: " + cont);
        cont++;
      }
    }
  }
}

The reason your code is running slow is this line:您的代码运行缓慢的原因是这一行:

txtMultiLineTextBox.Text = Mensaje + "\r\n" + txtMultiLineTextBox.Text;

When you set the constant in your while loop to any sizeable number - I found 1000 or more to be sizeable - then there there is a lot of work to build the string and then for the TextBox to display that string.当您将 while 循环中的常量设置为任何相当大的数字时 - 我发现 1000 或更多是相当大的 - 然后需要做很多工作来构建字符串,然后TextBox才能显示该字符串。

It will run fast if you just write this:如果你只写这个,它会运行得很快:

txtMultiLineTextBox.Text = Mensaje;

Your problem is the massive string.你的问题是巨大的字符串。

I don't know if it helps but don't call directly the showMessage from task.我不知道它是否有帮助,但不要直接从任务中调用 showMessage。 If you want to update the main form raise Event .如果你想更新主窗体 raise Event

Your program works correctly .您的程序运行正常

Maybe some small adjustments can be made like,也许可以做一些小的调整,比如,

  • change this.Invoke in this.txtMultiLineTextBox.Invoke在 this.txtMultiLineTextBox.Invoke 中更改 this.Invoke
  • use something like txtMultiLineTextBox.AppendText使用类似 txtMultiLineTextBox.AppendText 的东西

Further the tasks started in Form_Load messes up your form initialization a bit.此外,在 Form_Load 中启动的任务会稍微弄乱您的表单初始化。 For testing use a button.测试使用一个按钮。 But there is no freez at this side.但是这边没有冻结。 I tested your exact code on .NET 7, output gives me:我在 .NET 7 上测试了你的确切代码,输出给我:


this is the theread: 2 and the number: 99
this is the theread: 1 and the number: 99
this is the theread: 2 and the number: 98
this is the theread: 1 and the number: 98
this is the theread: 2 and the number: 97
this is the theread: 1 and the number: 97
this is the theread: 2 and the number: 96
this is the theread: 1 and the number: 96
.....
this is the theread: 2 and the number: 1
this is the theread: 1 and the number: 1
this is the theread: 2 and the number: 0
this is the theread: 1 and the number: 0

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

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