【问题标题】:Cross-threading C# [duplicate]跨线程 C# [重复]
【发布时间】:2016-04-18 19:47:37
【问题描述】:

我之前一直在学习线程,但使用的是 C++。现在我第一次尝试将此代码配置为正确工作,但没有 CheckIllegal ... = false。 我一直在尝试将代表和许多其他东西放在那里,但我遇到了同样的问题。两个线程都进入方法 WriteInLog ,我真的不知道如何使这项工作。 有人有想法和解释吗?

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


        }
        private int firstNum = 0;
        private int secondNum = 0;
        public Thread firstThread;
        public Thread secondThread;

        public  void WriteInLog(string message)
        {
            lock (textBox3)
            {
                textBox3.Text += message + Environment.NewLine;
            }
        }

        private void CheckInput()
        {
            int pom = 0;
            firstNum = int.Parse(textBox1.Text);
            secondNum = int.Parse(textBox2.Text);
            if (firstNum > secondNum) {
                pom = secondNum;
                secondNum = firstNum;
                firstNum = pom; }

            WriteInLog("Prvi broj: " + firstNum.ToString());
            WriteInLog("Drugi broj: " + secondNum.ToString());
        }


        private void button1_Click(object sender, EventArgs e)
        {
            CheckInput();

        }

        public delegate void ThreadSum();
        public delegate void ThreadUmn();
        public void Threadsumm()
        {
            int suma = 0;
            for (int i = firstNum; i < secondNum; i++)
                suma += i;
            WriteInLog("Suma= " + suma.ToString() + " kraj: " + DateTime.Now.ToString());

        }

        public  void ThreadUmno()
        {
            int umnozak = 1;
            for (int i = firstNum; i < secondNum; i++)
                umnozak*= i;
            WriteInLog("Umnozak= " + umnozak.ToString() + " kraj: " + DateTime.Now.ToString());
        }

        private void button2_Click(object sender, EventArgs e)
        {
            WriteInLog("Pocetak svih izracuna u: " + DateTime.Now.ToString());

            firstThread = new Thread(new ThreadStart(Threadsumm));
          secondThread = new Thread(new ThreadStart(ThreadUmno));


            firstThread.Start();
            secondThread.Start();


        }
    }
}

【问题讨论】:

  • 不要锁定文本框等 UI 元素,锁定对象类型的私有字段。

标签: c# multithreading delegates thread-safety


【解决方案1】:

要从非 UI 线程访问控制,您必须使用 Control.Invoke 方法 https://msdn.microsoft.com/en-us/library/a1hetckb(v=vs.110).aspx

你可以使用 BackgroundWorker 而不是线程 https://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

还有: WinForm Multithreading. Use backgroundWorker or not?

【讨论】:

    【解决方案2】:

    如果有人来到这里并想知道这个问题的确切答案,这里就是。 我不想改变任何东西,所以我学习了一些关于调用的东西。此外,这是代码

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Threading;
    
    
    namespace viseNitniRad
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
    
    
            }
            private int firstNum = 0;
            private int secondNum = 0;
            public Thread firstThread;
            public Thread secondThread;
    
            public  void WriteInLog(string message)
            {
                if (this.textBox3.InvokeRequired)
                {
                    ThreadSum ts = new ThreadSum(WriteInLog);
                    this.Invoke(ts, new object[] { message });
    
                }
                else
                {
                    this.textBox3.Text += message + Environment.NewLine;
                }
            }
    
            private void CheckInput()
            {
                int pom = 0;
                firstNum = int.Parse(textBox1.Text);
                secondNum = int.Parse(textBox2.Text);
                if (firstNum > secondNum) {
                    pom = secondNum;
                    secondNum = firstNum;
                    firstNum = pom; }
    
                WriteInLog("Prvi broj: " + firstNum.ToString());
                WriteInLog("Drugi broj: " + secondNum.ToString());
            }
    
    
            private void button1_Click(object sender, EventArgs e)
            {
                CheckInput();
    
        }
            public delegate void ThreadSum(string message);
            public delegate void ThreadUmn();
            public void Threadsumm()
            {
                int suma = 0;
                for (int i = firstNum; i < secondNum; i++)
                    suma += i;
                WriteInLog("Suma= " + suma.ToString() + " kraj: " + DateTime.Now.ToString());
    
            }
            public  void ThreadUmno()
            {
                int umnozak = 1;
                for (int i = firstNum; i < secondNum; i++)
                    umnozak*= i;
                WriteInLog("Umnozak= " + umnozak.ToString() + " kraj: " + DateTime.Now.ToString());
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                WriteInLog("Pocetak svih izracuna u: " + DateTime.Now.ToString());
    
                firstThread = new Thread(new ThreadStart(Threadsumm));
              secondThread = new Thread(new ThreadStart(ThreadUmno));
    
    
                firstThread.Start();
    
                secondThread.Start();
    
    
            }
        }
    }
    

    如您所见,我在函数 WriteInLog 中几乎没有更改,我删除了 lock 方法并设置了一个条件 if invokeRequired 来初始化 Delegate 以运行相同的方法,而不是调用他,如果不是,则只是更新相同的 textbox3。 谢谢你们! :)

    【讨论】:

      猜你喜欢
      • 2010-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多