C# 我创建了一个splashscreen,它可以正常工作,但它没有解决我所需要的问题我有如何在splashscreen加载时加载构造函数?
在表格1的顶部,我做了: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.
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个错误:
您正在创建一个新线程来处理初始屏幕的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;
}