Как запустить многопоточное приложение? - PullRequest
0 голосов
/ 28 мая 2009

Эти коды генерируют нам эту ошибку:

Операция между потоками недопустима: доступ к элементу управления progressBar2 осуществляется из потока, отличного от потока, в котором он был создан.

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

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

        ThreadStart ts1;
        ThreadStart ts2;
        Thread t1;
        Thread t2;

        private void btnStart_Click(object sender, EventArgs e)
        {
            ts1 = new ThreadStart(z1);
            ts2 = new ThreadStart(z2);

            t1 = new Thread(ts1);
            t2 = new Thread(ts2);

            t1.Start(); 
            t2.Start();

            btnStart.Enabled = false;
        }

        public void z1()
        {

            for (int i = 1; i < 60; ++i)
            {
                progressBar1.Value += 1;
                for (int j = 1; j < 10000000; ++j)
                {
                    j += 1;
                }
            }
        }

        public void z2()
        {
            for (int k = 1; k < 100; ++k)
            {
                progressBar2.Value += 1;
                for (int j = 1; j < 25000000; ++j)
                {
                    j += 1;
                }
            }
        }

        private void btnstop_Click(object sender, EventArgs e)
        {
            t1.Suspend(); 
            t2.Suspend();
        }

        private void btnContinue_Click(object sender, EventArgs e)
        {
            t1.Resume(); 
            t2.Resume();

        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            if (t1.IsAlive)
            {
                MessageBox.Show("Çalışan threadler var program sonlanamaz.");
            }
            else
            {
                this.Close();
            } 

        }
    }
}

Ответы [ 3 ]

7 голосов
/ 28 мая 2009

Вы не можете получить доступ к элементу управления пользовательского интерфейса в потоке, отличном от потока пользовательского интерфейса, ответственного за этот элемент управления.

См. Страницу WinForms в моем руководстве по созданию потоков, а также поиск учебных пособий по BackgroundWorker, компоненту, представленному в .NET 2.0, который значительно облегчает жизнь (особенно для индикаторов выполнения).

Кроме того, я бы старался избегать использования Thread.Suspend / Resume, предпочитая более кооперативный подход (например, с Monitor.Wait / Pulse). Это позволяет избежать приостановки потока, пока он удерживает блокировку и т. Д.

1 голос
/ 28 мая 2009

Для z1 и z2 сделайте это: Добавить zSafe () Вызовите zSafe () в пределах z () после проверки InvokeRequired.

public void z1Safe()
        {

            for (int i = 1; i < 60; ++i)
            {
                progressBar1.Value += 1;
                for (int j = 1; j < 10000000; ++j)
                {
                    j += 1;
                }
            }
        }

        public void z1()
        {

            if (this.InvokeRequired)
            {
                this.Invoke((MethodInvoker)delegate { z1Safe(); });
            }
            else
                z1Safe();
        }

Я только что реализовал подобное решение в форме Windows для асинхронного вызова, и оно отлично работает.

0 голосов
/ 28 мая 2009

Межпотоковые исключения очень распространены, когда вы работаете с многопоточным приложением, и это происходит, когда вы пытаетесь вызвать элемент элемента управления в потоке, отличном от его собственного потока. Чтобы избежать проверки свойства InvokeRequired этого элемента управления и вызывать делегата в его собственном потоке или использовать BackgroundWorker для запуска процесса в фоновом режиме (другой поток) и обрабатывать его события. Когда вы обрабатываете события BackgroundWorker, методы основного обработчика будут выполняться в главном потоке, поэтому нет необходимости вызывать делегат .

Здесь Вы можете найти некоторую информацию о BackgroundWorker

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...