繁体   English   中英

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

[英]C# Form MultiThreading, Need a tricky solution

我在c#中使用多线程存在问题。 我有一个复杂的计算事物,必须在主线程上运行,这意味着它必须在主窗口上运行。

我的程序运行如下:

  • 首先它将打开一个新窗口,用户可以输入参数
  • 然后它将运行必须在主线程中运行的复杂计算(我无法更改它,我正在使用阻止在不同线程中调用计算事物的库,如果我使用不同的线程,它将带有异常) )。
  • 仿真运行时,它还将打开一个监视计算的新窗口,它还将为此绘制图形,我需要它是实时的。

问题:由于长时间在主线程上运行复杂的计算,因此监视窗口将挂起并且没有响应。 有什么棘手的方法可以解决这个问题吗? 我可以使用其他线程来运行监视窗口吗? 主要形式是不响应,但不能监视窗口。 在这里,我放置了一些类似于我的程序的代码,而不是我的真实程序,但是流程是一样的。

Main Form (将运行计算事物的主线程,并从用户输入参数)

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

我不能对必须在主线程中运行的方法做任何事情,我正在使用库来阻止其方法从其他方法运行,谢谢。

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM