Form1.cs的
public Form1()
{
Thread SplashThread = new Thread(new ThreadStart(SplashScreen));
SplashThread.Start();
Thread.Sleep(5000);
SplashThread.Abort();
InitializeComponent();
this.BringToFront();
PlayerOne[1] = new BladeWarrior();
PlayerOne[2] = new FistWarrior();
PlayerOne[3] = new Archer();
PlayerOne[4] = new RedMage();
PlayerOne[5] = new BlueMage();
}
public void SplashScreen()
{
Application.Run(new SplashScreen());
}
SplashScreen.cs
public SplashScreen()
{
InitializeComponent();
LoadGearFiles LoadGear = new LoadGearFiles();
LoadGear.StartPatching(this);
}
Timer t = new Timer();
void t_Tick(object sender, EventArgs e)
{
if (LoadingBar.Value == 100) t.Stop();
}
LoadGearFiles.cs
public void StartPatching(SplashScreen Splash)
{
Splash.PatchingLabel.Text = "Patching in progress! This may take a moment or two!";
Thread.Sleep(SleepTime);
Splash.LoadingBar.Value += 25;
LoadWeapons(Splash);
Splash.LoadingBar.Value += 25;
LoadArmor(Splash);
Splash.LoadingBar.Value += 25;
LoadRings(Splash);
Splash.LoadingBar.Value += 25;
Splash.PatchingLabel.Text = "Patch Complete!";
}
我的问题是我的启动画面显示但基于Thread.Sleep(5000)关闭而不是进度条值等于其最大值。如果我注释掉Thread.Sleep(5000),那么启动画面几乎会立即关闭。在LoadGearFiles类中,没有什么特别之处,只是流读取器/写入器读取和写入记事本文件,将信息加载到数组中。他们成功地读/写/填充。此外,在装载齿轮文件类中,我在读取或写入某些文件后增加进度条的值。这里似乎是我的问题。我应该采取什么样的逻辑/句法方法?
答案 0 :(得分:1)
我假设您正在使用代码中的WinForms。看起来您希望在最短时间内显示启动画面,或者直到所有文件都成功加载 - 以最后为准。
假设您可以访问C#4.0的Task
和C#5.0的async/await
关键字,我强烈建议您远离Thread.Sleep
。这是一个相当古老的结构,对现代多线程程序来说效率不高。即使您没有后者,也可以使用Task
,您会看到为什么使用它们的原因越多。
让我们将你的逻辑分解为任务:
让我们以C#代码的形式来看待它(我在很大程度上不是在IDE中编写代码):
public async void ShowSplashScreen(TimeSpan minimumDuration)
{
// Show the splash screen to the user.
var splashScreen = new SplashScreen();
splashScreen.Show();
splashScreen.UpdateProgress(0); // reset progress bar
// Record when we started to load data for calculating the elapsed time later on.
var startTime = DateTime.Now;
// Load all of our data types asynchronously from file.
var warrior = await LoadDataFileAsync("warrior.dat");
splashScreen.UpdateProgress(20); // 20%
var archer = await LoadDataFileAsync("archer.dat");
splashScreen.UpdateProgress(40); // 40%
var redMage = await LoadDataFileAsync("redMage.dat");
splashScreen.UpdateProgress(60); // 60%
var blueMage = await LoadDataFileAsync("blueMage.dat");
splashScreen.UpdateProgress(80); // 80%
var fistWarrior = await LoadDataFileAsync("fistWarrior.dat");
splashScreen.UpdateProgress(100); // 100% -- all done
// Determine the elapsed time to load all data files, and the remaining time to display the splash screen.
var elapsedTime = DateTime.Now - startTime;
var remainingTimeToWait = minimumDuration - elapsedTime;
// If we've completed early, wait the remaining duration to show the splash screen.
if(remainingTimeToWait > TimeSpan.Zero)
await Task.Delay(remainingTimeToWait);
// Done loading, close the splash screen.
splashScreen.Close();
}
现在,您的LoadDataFileAsync
方法看起来像这样:
Task<object> LoadDataFileAsync(string file)
{
// Do your work to load your data file into an object here.
}
编辑:我已经收到您关于使用.NET 4.0的评论的提醒,因此您有Task
但不一定是async/await
。在这种情况下,您仍然可以将代码分解为Task
,但必须使用.ContinueWith()
。
请点击此处查看一些好例子:How to: Chain Multiple Tasks with Continuations
答案 1 :(得分:1)
在Timer_Tick中打开您的表单:
void Timer1_Tick(object sender, EventArgs e)
{
progressBar1.PerformStep();
if(progressBar1.Value == 100)
{
Timer.Enabled = false;
Form1 form1 = new Form1();
form1.Show();
this.Hide(); //or Close maybe (test them both)
}
}