C # Form MultiThreading, нужно сложное решение - PullRequest
0 голосов
/ 31 октября 2011

У меня проблема с использованием многопоточности в c #.У меня есть сложная вычислительная вещь, которая должна выполняться в главном потоке, значит, она должна выполняться в главном окне.

Моя программа работает так:

  • Сначала открывается новое окно, и пользователь может ввести параметр
  • Затем запускаются сложные вычисления, которые должны выполняться восновной поток (я не могу изменить это, я использую библиотеку, которая предотвращает вызов вычислительной вещи в другом потоке, если я использую другой поток, это будет с исключением).
  • Когда запустится симуляция, он также откроет новое окно, которое отслеживает вычисления, он также построит график для него, и мне нужно, чтобы оно было в режиме реального времени.

Проблема: Поскольку в течение длительного времени сложные вычисления выполняются в основном потоке, окно мониторинга будет зависать и не отвечать.Есть какой-нибудь хитрый способ решить эту проблему?Могу ли я использовать другой поток для запуска окна мониторинга?основная форма подходит для того, чтобы не отвечать, но не подходит для окна мониторинга.Здесь я поместил некоторый код, который похож на мою программу, а не на мою настоящую программу, но поток такой же.

Основная форма (основной поток, который будет выполнять вычислительную функцию, и входной параметр изпользователь)

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

    private void button1_Click(object sender, EventArgs e)
    {
        compute c = new compute();
        c.computing();
    }
}

Форма графика (Мониторинг графика, который будет составлять график, необходимый в режиме реального времени)

    public graphic()
    {
        InitializeComponent();
    }

    private void label1_Click(object sender, EventArgs e)
    {

    }

    public void updateLabel(int count)
    {
        label1.Text = "Current i value:  " + count;
    }

Вычислить класс (занимаясь вычислениями)

class compute
{
    delegate void writeToForm(int i);
    graphic g = new graphic();

    public compute()
    {
        g.Show();
    }
    public void computing()
    {
       //THIS PART MUST RUN ON THE MAIN THREAD, DON'T MAKE IT ON THE OTHER THREAD
       //IT IS A MUST
        int count = 0;
        //THIS IS THE LONG TIME COMPUTING THING
        for (int i = 0; i < 100; i++)
        {
            count += i;
            updateLabel(count);
            Thread.Sleep(2000);
        }
    }

    private void updateLabel(int count)
    {
        if (g.InvokeRequired)
        {
            g.Invoke(new writeToForm(updateLabel), new object[] { count });
            return;
        }
        g.updateLabel(count);
    }
}

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

Ответы [ 3 ]

1 голос
/ 31 октября 2011

Если вам необходимо выполнить вычисления в главном потоке, измените код, как показано ниже

public void computing()
    {
       //THIS PART MUST RUN ON THE MAIN THREAD, DON'T MAKE IT ON THE OTHER THREAD
       //IT IS A MUST
        int count = 0;
        //THIS IS THE LONG TIME COMPUTING THING
        for (int i = 0; i < 100; i++)
        {
            count += i;
            updateLabel(count);
            Thread.Sleep(2000);
            Application.DoEvents(); //tell windows to process pending message.
        }
    }
0 голосов
/ 31 октября 2011

Возможный обходной путь - написать форму мониторинга в другой программе, которую ваша основная программа может запустить до выполнения метода computing. Да, ваша основная форма все еще будет зависать (но вы говорите, что это не проблема?).

Вы можете связаться с вашим основным приложением, возможно, открыв локальное TCP-соединение (которое может без проблем работать в другом потоке). Это может отправлять команды в приложение мониторинга (или любые другие подключенные клиенты TCP, если вы хотите), которое получит их и использует метод Control.Invoke для обновления интерфейса.

0 голосов
/ 31 октября 2011

Вы можете попробовать позвонить Application.DoEvents после обновления графика во втором окне.Это обрабатывает все оконные сообщения, что должно позволить обновлять ваше второе окно.

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