【问题标题】:Thread windows form线程窗口窗体
【发布时间】:2017-11-23 08:19:09
【问题描述】:

我目前正在处理一个需要处理大量数据的项目,因此我决定创建一个 Windows 窗体,通知用户正在进行处理。当然,我必须使用另一个线程。但是我需要多次运行这个窗口(不是同时,但它第一次启动良好,第二次启动不好),我必须有一个启动线程的方法和另一个停止它的方法以及一个标签将根据在另一个线程中的方法中执行的循环次数显示不同的内容(这很棘手^^)。

我读了很多关于线程的文章,但我仍然没有找到如何去做。 我做的一些代码:

 public partial class Progress : Form
{

    Thread thr = null;

    public Progress()
    {
        InitializeComponent();
        try
        { 
             thr = new Thread(() => this.ShowDialog());
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    public void Start()
    {
        thr.Start();           
        //this.ShowDialog();
    }

    public void Stop()
    {
        thr.Abort();
        thr.Join();
        //this.Close();
    }

我想使用类似的东西,我该怎么做?

other class {
  Progress t = new Progress();
  t.Start();
  firstFunction();
  SecondBigFunction(t);
  threeFunction();
  t.Stop();
}

SecondBigFunction(Thread t){
  while(list.lenght > 0){
    // Do somework
    t.labelToChange += 1;
  }
}

谢谢。

【问题讨论】:

    标签: c# multithreading


    【解决方案1】:

    您可以使用 backgroundworker 类来完成您的任务

    private BackgroundWorker bg1 = new BackgroundWorker();
     bg1.DoWork += bg1_DoWork;
    
     private void bg1_DoWork(object sender, DoWorkEventArgs e)
            {
               //the function you want to execute
            }
    

    同样,您可以在每个后台工作人员中定义具有不同功能的各种后台工作人员。

    最后按照您希望函数执行的顺序调用后台工作程序(所有这些函数将同时执行)。

    【讨论】:

    • 所以我必须将 showDialog() 或三个 Function() 放在 private void bg1_DoWork(object sender, DoWorkEventArgs e) 中?
    • 如果你把showDialog()放在DoWork()中,那么把这三个函数放在其他backgrounworker中。这将运行函数(一个接一个),对话框将显示(同时)。
    【解决方案2】:

    我不确定,但它可以帮助你。

    labeltoChange.Invoke((MethodInvoker)(() => labeltoChange.Text+=1));
    

    【讨论】:

    • 不错!它工作得很好,但不是得到 1 然后 2 然后 3 我得到 1 然后 11 然后 111 ...
    • 这是关于在文本中添加 1。您应该设置整数值并每次将其设置为文本
    • 好的,我做的事情安全吗?使用踏蚁 thr.abort(),因为我到处都能看到“使用线程不安全...olalala”^^
    【解决方案3】:

    通常所有的 UI 工作都应该在同一个线程上执行。 因此,尝试在单独的线程上启动 Form 通常只会导致问题。

    至少您需要使用 Invoke,它将使用 UI 线程来更新控件。如此有效意味着您只使用一个线程。

    可以这样做,有关更多详细信息,您应该看到这个; In WinForms, Is More than One Thread Possible in the UI?

    还有这个; Multiple UI Threads - Winforms

    更好的做法是将“艰苦的”计算放在后台工作线程中,然后在完成后更新 UI。

    这篇文章给出了一个例子; https://www.codeproject.com/Articles/99143/BackgroundWorker-Class-Sample-for-Beginners

    【讨论】:

      【解决方案4】:
      labeltoChange.Invoke((MethodInvoker)(() => labeltoChange.Text+=1));
      

      这个方法是个好方法,只是当你做labeltoChange.Text+=1你增加数字不要做加法。

      如果要添加到文本框中,请使用:

      labeltoChange.Invoke((MethodInvoker)(() => Convert.ToInt32(labeltoChange.Text) + 1));
      

      【讨论】:

      • 是的,但我的标签之前也有一个文本,它只是在最后我添加了数字,所以我创建了一个只有数字的另一个标签,我这样做 recherche += 1; t.lblNbRecherche.Invoke((MethodInvoker)(() => t.lblNbRecherche.Text = recherche.ToString()));谢谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多