交叉线程C#

时间:2016-04-18 19:47:38

标签: c# multithreading delegates thread-safety

我之前一直在学习线程,但是在C ++中。现在我第一次尝试将此代码配置为corectly但没有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();


        }
    }
}

2 个答案:

答案 0 :(得分:0)

要从非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?

答案 1 :(得分:0)

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

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();


        }
    }
}

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方法,并且如果invokeRequired初始化Delegate以运行相同的方法而不是调用他,只是为了更新相同的textbox3。 谢谢你们! :)