C#Form MultiThreading,需要一个棘手的解决方案

时间:2011-10-31 09:53:29

标签: c# multithreading forms

我在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 个答案:

答案 0 :(得分:1)

如果您必须在主线程中执行计算,请修改您的代码,如下所示

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.
        }
    }

答案 1 :(得分:0)

您可以在第二个窗口中更新图表后尝试调用Application.DoEvents。这将处理所有窗口消息,这将允许您更新第二个窗口。

答案 2 :(得分:0)

可能的解决方法是将监控表单写入另一个程序,该程序可以在执行computing方法之前由主程序启动。是的,您的主表单仍然会挂起(但您说这不是问题吗?)。

您可以通过打开本地TCP连接(可以在不同的线程上运行而没有问题)与您的主应用程序进行通信。这可以将命令发送到监视应用程序(或任何其他连接的TCP客户端,如果您愿意),这将接收这些命令并使用Control.Invoke方法更新UI。