【问题标题】:c# communication between splashscreen and mainform into different threadc#splashscreen和mainform之间的通信进入不同的线程
【发布时间】:2017-05-12 17:02:48
【问题描述】:

我发现该示例 (Communicate between two windows forms in C#) 可以正常工作,但当两个表单位于不同线程中时就不行。

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

这个脚本的重点是在 MainForm 工作时修改启动画面中 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);
            }
        }
    }
}

【问题讨论】:

    标签: c# multithreading winforms splash-screen


    【解决方案1】:

    您需要调用 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);
            }
    

    【讨论】:

    • 我仍然不明白 Invoke() 是如何工作的,它说不可能将 lambda 表达式转换为委托类型...
    • 对不起 - 我的一个小错误 - 查看编辑后的答案!
    • 我写过这个:this.splashy.Invoke((MethodInvoker)delegate { this.splashy.LabelText = i; });但仍然是同样的错误
    • i 不是字符串!
    • 使用i.ToString()设置文字
    猜你喜欢
    • 1970-01-01
    • 2011-01-05
    • 2015-08-11
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多