c#splashscreen和mainform之间的通信进入不同的线程

时间:2016-12-28 11:54:14

标签: c# multithreading winforms splash-screen

我发现这个例子(Communicate between two windows forms in C#)工作正常,但两个表格在不同的帖子中时却没有。

我在MainForm的第20行有一个“System.NullReferenceException”(this.splashy.LabelText = i;)

此脚本的目的是在MainForm执行其工作时修改splashscreen中progressBar的宽度。

提前致谢!

以下是两个c#类和程序文件:

//Program.cs
using System;
using System.Threading;
using System.Windows.Forms;
namespace GIS
{
    static class Program
    {
        public static SplashScreen splashy = null;
        /// <summary>
        /// Point d'entrée principal de l'application.
       /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Thread splashThread = new Thread(new ThreadStart(
            delegate
            {
                //SplashScreen splashy = new SplashScreen();
                splashy = new SplashScreen();
                Application.Run(splashy);
            }
            ));
            splashThread.SetApartmentState(ApartmentState.STA);
            splashThread.Start();
            //run form - time taking operation
            MainForm mainForm = new MainForm(splashy);
            mainForm.Load += new EventHandler(mainForm_Load);
            Application.Run(mainForm);
        }
        static void mainForm_Load(object sender, EventArgs e)
        {
            //close splash
            if (splashy == null)
            {
                return;
            }
            splashy.Invoke(new Action(splashy.Close));
            splashy.Dispose();
            splashy = null;
        }
    }
}

//SplashScreen.cs
using System;
using System.Windows.Forms;
namespace GIS
{
    public partial class SplashScreen : Form
    {
        public SplashScreen()
        {
            InitializeComponent();
        }
        public int LabelText
        {
            get 
            { 
                return rectangleShape1.Width; 
            }
            set 
            { 
                rectangleShape1.Width = value; 
            }
       }
    }
}

//MainForm.cs
using System.Threading;
using System.Windows.Forms;
namespace GIS
{
    public partial class MainForm : Form
    {
        private SplashScreen splashy = null;
        public MainForm(Form callingForm)
        {
            splashy = callingForm as SplashScreen;
            InitializeComponent();
            doWork();
        }
        private void doWork()
        {
            for(int i = 0; i < 100; i++)
            {
            this.splashy.LabelText = i;
            Thread.Sleep(10);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

你需要调用SplashScreen来改变其他线程的价值,比如

this.splashy.Invoke((MethodInvoker) delegate { this.splashy.LabelText = "Requested" + repeats + "Times"; });

注意构造函数

splashy = callingForm as SplashScreen;

允许splashy为空 - 这会导致您当前的NullReferenceException

此问题位于此剪辑中:

        Thread splashThread = new Thread(new ThreadStart(
        delegate
        {
            splashy = new SplashScreen();
            Application.Run(splashy);
        }
        ));
        splashThread.SetApartmentState(ApartmentState.STA);
        splashThread.Start();
        //run form - time taking operation
        MainForm mainForm = new MainForm(splashy);

在您传递新线程之前,创建SplashScreen实例的速度并不快。结果 - 您正在传递null

通过在线程开始之前创建splashy来修复它:

        splashy = new SplashScreen();
        Thread splashThread = new Thread(new ThreadStart(
        delegate
        {
            Application.Run(splashy);
        }