我创建了一个它的工作的启动画面,但它没有解决我需要的我怎么能加载splahshscreen加载时的构造函数?
在form1的顶部,我做了:
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();
然后:
public void SplashScreen() { Application.Run(new SplashScreen()); }
在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工作时,它将完成构造函数中的所有内容,包括computer.Open();
因此,当启动闪屏时,它将显示我的程序ato nce而无需等待。
我该怎么做 ?
编辑**
这就是我现在在form1的顶部所做的:
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
是可以避免的所有其他费用。)
然后我们只在主线程中显示启动画面,当它关闭时,我们会显示主窗体。 我们还将长时间运行的进程的结果传递给主表单,因此您需要为其创建一个属性才能将这些结果传递给它。 我们还可以利用任务并行库的取消function来确保启动屏幕在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(); new System.Threading.Timer(_ => tcs.TrySetResult(true), null, (long)timeout.TotalMilliseconds, Timeout.Infinite); return tcs.Task; }