C#多线程

Dez*_*igo 5 .net c# multithreading winforms

我有C#多线程的问题.
表格内容是两个按钮和两个标签.

如果我按下第一个按钮,从1..00到60000循环,更新label1.(它的工作原理)

如果我按下第二个按钮,从1..6到6000循环更新label2,(我的表格滞后).(没有回应)
请帮忙!

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

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

        private void button1_Click(object sender, EventArgs e)
        {

            Thread thread = new Thread(new ThreadStart(countNumbers));
            thread.IsBackground = true;
            thread.Start();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Thread thread2 = new Thread(new ThreadStart(countNumbers2));
            thread2.Start();
        }

        public void countNumbers()
        {
            try
            {
                for (int i = 0; i < 60000; i++)
                {
                   this.Invoke((MethodInvoker)delegate()
                   {
                        label2.Text = "" + i.ToString();
                   }
                );
                }
            }
            catch (Exception e)
            {

            }
        }

        public void countNumbers2()
        {
            try
            {
                for (int i = 0; i < 60000; i++)
                {
                    this.Invoke((MethodInvoker)delegate()
                    {
                        label4.Text = "" + i.ToString();
                    }
                 );
                }
            }
            catch (Exception e)
            {

            }
        }



        private void label3_Click(object sender, EventArgs e)
        {

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jak*_*lås 5

尝试Forms.Timer在表单中使用a 并定期轮询值以受控方式更新标签.更新你的方式把用户界面的方式,以多系统负载.
一个System.Windows.Forms.Timer运行GUI线程.

只需确保以某种方式保护共享资源,此示例使用volatile成员来处理线程同步.

没有需要额外的Thread.Sleep(10),它只是有模拟一些负载.

private volatile int _counter;
private readonly Timer _timer = new System.Windows.Forms.Timer();

public Form1()
{
    InitializeComponent();

    _timer.Tick += TimerTick;
    _timer.Interval = 20;  // ~50 Hz/fps
    _timer.Start();
}

void TimerTick(object sender, EventArgs e)
{
    _label.Text = _counter.ToString();
}

private void Form1_Load(object sender, EventArgs e)
{
    Thread thread = new Thread(CountNumbers) {IsBackground = true};
    thread.Start(); 
}

public void CountNumbers()
{
    for (int i = 0; i < 60000; i++)
    {
        _counter++;
        Thread.Sleep(10);  // <-- Simulated work load
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,您可以轻松扩展此示例以使您的示例适合两个不同的计数器,这些计数器在单独的线程上计算,但仍然只使用一个Timer来更新整个UI.


Dev*_*erX 1

尝试使用lock语句

  lock (this)
      {
        label2.Text = "" + i.ToString();
       }
Run Code Online (Sandbox Code Playgroud)

你应该将你的代码更改为

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication23
{
    public partial class Form3 : Form
    {
        public Form3()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            Thread thread = new Thread(new ThreadStart(countNumbers));
            thread.IsBackground = true;
            thread.Start();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Thread thread2 = new Thread(new ThreadStart(countNumbers2));
            thread2.Start();
        }

        public void countNumbers()
        {
            try
            {
                for (int i = 0; i < 60000; i++)
                {
                   this.Invoke((MethodInvoker)delegate()
                   {
                       lock (this)
                       {
                           label2.Text = "" + i.ToString();
                       }
                   }
                );
                }
            }
            catch (Exception e)
            {

            }
        }

        public void countNumbers2()
        {
            try
            {
                for (int i = 0; i < 60000; i++)
                {
                    this.Invoke((MethodInvoker)delegate()
                    {
                        lock (this)
                        {
                            label4.Text = "" + i.ToString();
                        }
                    }
                 );
                }
            }
            catch (Exception e)
            {

            }
        }



        private void label3_Click(object sender, EventArgs e)
        {

        }
    }
}
Run Code Online (Sandbox Code Playgroud)