C# 我创建了一个splashscreen,它可以正常工作,但它没有解决我所需要的问题我有如何在splashscreen加载时加载构造函数?

C# 我创建了一个splashscreen,它可以正常工作,但它没有解决我所需要的问题我有如何在splashscreen加载时加载构造函数?,c#,winforms,C#,Winforms,在表格1的顶部,我做了: InitializeComponent(); Thread t = new Thread(new ThreadStart(SplashScreen)); t.Start(); Thread.Sleep(5000); textBox3_text_valid = 0; label8.Visible = false; label8.

在表格1的顶部,我做了:

InitializeComponent();

            Thread t = new Thread(new ThreadStart(SplashScreen));
            t.Start();
            Thread.Sleep(5000);
            textBox3_text_valid = 0;
            label8.Visible = false;
            label8.Visible = false;
            Logger.exist();
            dt1 = DateTime.Now;
            label1.Text = dt1.ToLongTimeString();
            temperature_label = new Label();
            textMode_label = new Label();
            this.Controls.Add(textMode_label);
            this.Controls.Add(temperature_label);

            temperature_label.Location = new Point(260, 200);
            temperature_label.Height = 250;
            temperature_label.Width = 500;
            temperature_label.ForeColor = Color.Red;
            temperature_label.Font = new Font("Arial", 35, FontStyle.Bold);

            textMode_label.Location = new Point(350, 200);
            textMode_label.Height = 250;
            textMode_label.Width = 500;
            textMode_label.ForeColor = Color.Blue;
            textMode_label.Font = new Font("Arial", 35, FontStyle.Bold);
            textMode_label.Text = " - הטמפרטורה כעת";

            path_log = Path.GetDirectoryName(Application.LocalUserAppDataPath) + @"\log";
            fullPath = path_log + log_file_name;

            timer = new System.Windows.Forms.Timer();
            timer.Interval = 100;
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();
            textBox3.Text = Options_DB.Get_textBox3_time();
            computer = new Computer();
            computer.Open();
            computer.GPUEnabled = true;

            t.Abort();
我遇到的问题是线路:

computer.Open();
它需要3-5秒才能完成这一行。 所以我在构造函数中添加了一个splahscreen代码,我做了:

Thread t = new Thread(new ThreadStart(SplashScreen));
t.Start();
Thread.Sleep(5000);
然后:

t.Abort();
然后:

在SplashScreen窗体中,我执行了以下操作:

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

        private void SplashScreen_Load(object sender, EventArgs e)
        {

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            progressBar1.Increment(1);
            if (progressBar1.Value == 100) timer1.Stop(); 
        }
    }
问题是,当SplashScreen结束加载时,progressBar已100%完成向右移动,程序正在等待计算机。Open();要完成的生产线

我希望当splashscreen中的progressBar工作时,它将完成构造函数中的所有工作,包括计算机

因此,当splashscreen完成时,它将显示我的程序,而无需等待

我怎么做

编辑**

这就是我现在在表格1顶部所做的:

Computer computer = new Computer();
SplashScreen splash = new SplashScreen();
然后,构造器:

InitializeComponent();

            Task.Run(() => computer.Open())
    .ContinueWith(t => { }
        , new CancellationTokenSource(TimeSpan.FromSeconds(5)).Token)
    .ContinueWith(t => splash.Close());
            textBox3_text_valid = 0;
            label8.Visible = false;
            label8.Visible = false;
            Logger.exist();
            dt1 = DateTime.Now;
            label1.Text = dt1.ToLongTimeString();
            temperature_label = new Label();
            textMode_label = new Label();
            this.Controls.Add(textMode_label);
            this.Controls.Add(temperature_label);

            temperature_label.Location = new Point(260, 200);
            temperature_label.Height = 250;
            temperature_label.Width = 500;
            temperature_label.ForeColor = Color.Red;
            temperature_label.Font = new Font("Arial", 35, FontStyle.Bold);

            textMode_label.Location = new Point(350, 200);
            textMode_label.Height = 250;
            textMode_label.Width = 500;
            textMode_label.ForeColor = Color.Blue;
            textMode_label.Font = new Font("Arial", 35, FontStyle.Bold);
            textMode_label.Text = " - הטמפרטורה כעת";

            path_log = Path.GetDirectoryName(Application.LocalUserAppDataPath) + @"\log";
            fullPath = path_log + log_file_name;

            timer = new System.Windows.Forms.Timer();
            timer.Interval = 100;
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();
            textBox3.Text = Options_DB.Get_textBox3_time();
            computer = new Computer();
            computer.Open();
            computer.GPUEnabled = true;

            Application.Run(splash);
            Application.Run(new Form1() { Computer = computer });
我有3个错误:

  • 错误1“System.Threading.Tasks.Task”不包含“Run”的定义D:\C-Sharp\NvidiaTemp\NvidiaTemp\NvidiaTemp\Form1.cs

  • 错误2“System.Threading.CancellationTokenSource”不包含接受1个参数的构造函数

  • 错误3“NvidiaTemp.Form1”不包含“计算机”的定义


  • 您正在创建一个新线程来处理初始屏幕的UI,以便您的第一个UI线程可以继续执行其他一些非基于UI的处理

    不要那样做

    多个UI线程是一个非常糟糕的主意。它们很难使用,导致代码错误,不能很好地使用框架代码,等等。除非你真的知道自己在做什么,否则就不要这样做,即使这样,也要不惜一切代价避免这样做

    相反,在非UI线程中执行非UI工作,并在单个UI线程中执行整个应用程序的所有UI工作

    另一个问题是,我们希望在显示主窗体之前显示启动屏幕,以便处理该问题,我们将移动到program.cs文件以更改整个应用程序的启动方式

    首先,我们将创建启动屏幕和处理长时间运行的工作的对象,然后在另一个线程中启动长时间运行的工作,并指示它在完成时关闭启动屏幕。(请注意,我们在这里很好地关闭了表单,而不是使用
    Abort
    Abort
    是要不惜一切代价避免的事情。)

    然后我们只在主线程中显示启动屏幕,当它关闭时,我们显示主窗体。我们还将长时间运行的流程的结果传递给主窗体,因此您需要为它创建一个属性,以便能够将这些结果传递给主窗体。我们还可以利用Task Parallel Library的取消功能,确保启动屏幕在5秒后关闭,即使此时任务尚未完成:

    SplashScreen splash = new SplashScreen();
    Computer computer = new Computer();
    Task.Factory.ContinueWhenAny(new[]{
        Task.Factory.StartNew(() => computer.Open()),
        Delay(TimeSpan.FromSeconds(5))
    },
    t => splash.Close());
    
    Application.Run(splash);
    Application.Run(new MainForm() { Computer = computer });
    
    这里有一个
    Delay
    实现,因为您使用的是4.0,无法访问4.5中添加的版本:

    public static Task Delay(TimeSpan timeout)
    {
        var tcs = new TaskCompletionSource<bool>();
        new System.Threading.Timer(_ => tcs.TrySetResult(true),
            null, (long)timeout.TotalMilliseconds, Timeout.Infinite);
        return tcs.Task;
    }
    
    公共静态任务延迟(时间跨度超时)
    {
    var tcs=new TaskCompletionSource();
    新的System.Threading.Timer(=>tcs.TrySetResult(true),
    null,(长)timeout.total毫秒,timeout.Infinite);
    返回tcs.Task;
    }
    
    Servy尝试了您的代码,但我收到了错误。现在更新了我的问题。@user3117033这是因为您使用的是.NET 4.0,其中一些功能是在4.5中添加的。请参见编辑。关于你的第三点,我在回答中已经提到了;您需要添加一个新属性,以便可以传入该属性。
    public static Task Delay(TimeSpan timeout)
    {
        var tcs = new TaskCompletionSource<bool>();
        new System.Threading.Timer(_ => tcs.TrySetResult(true),
            null, (long)timeout.TotalMilliseconds, Timeout.Infinite);
        return tcs.Task;
    }