我一直在努力解决这个问题。在涉及线程时我很困惑。
我要做的是在功能中暂停1暂停并继续执行该功能,直到另外1秒暂停,最后完成功能。
public partial class SplashScreen : Form
{
public SplashScreen()
{
InitializeComponent(); // initalize splash screen
DatabaseStatus(); // set database connection
getUserInfo(); // get user information
showInfo(); // show app information on splash screen
System.Threading.Thread wa = new System.Threading.Thread(new System.Threading.ThreadStart(checkUser));
wa.IsBackground = true;
wa.Start();
}
void checkUser()
{
if (RegisteredUser)
{
richTextBox1.Text += "Loading user settings..."; // SHOW THIS TEXT AND WAIT 1 SECOND UNTIL NEXT
System.Threading.Thread.Sleep(1000);
if (DATABASE_CONNECTION)
{
richTextBox1.Text += "Loging on...";
// WAIT AGAIN 1 SEC AND CONTINUE///
LoginCheck login = new LoginCheck(USER_NAME, PASSWORD);
if (login.LOGIN_SUCESS)
{
richTextBox1.Text += "Sucess!";
// SHOW THIS TEXT AND WAIT 1 SEC UNTIL SPLASH SCREEN FADE OUT//
//MessageBox.Show(login.HASH);
opac.Interval = 12;
opac.Start();
opac.Tick += new EventHandler(dec);
}
else
{
MessageBox.Show(login.HASH);
}
}
}
else
{
richTextBox1.Text += "Not user profile found...";
// ask user to register
}
}
}
我放置评论的位置是我希望线程暂停并继续...
有人有任何意见吗?
由于
答案 0 :(得分:2)
首先,您必须知道何时使用WinForms(以及WPF / Silverlight ......对吗?)您不能,也不应该从创建表单/控件的原始文件之外的任何其他线程操作UI元素。
如果您需要执行异步工作,则需要使用Invoke
或BeginInvoke
将UI工作转换回表单或控件的线程。另外,考虑使用委托(MethodInvoker
很方便)而不是创建自己的线程。
此外,您需要在Load
事件期间或之后启动异步工作,否则您的逻辑将在表单显示之前开始执行(请参阅下面的示例)。
我举了你的例子并把它放到我自己的简化样本中。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
RegisteredUser = true;
DATABASE_CONNECTION = true;
}
private void UpdateStatus(string message)
{
BeginInvoke(new MethodInvoker(() => richTextBox1.Text += message));
}
private void CheckUser()
{
if (RegisteredUser)
{
UpdateStatus("Loading user settings..."); // SHOW THIS TEXT AND WAIT 1 SECOND UNTIL NEXT
System.Threading.Thread.Sleep(1000);
if (DATABASE_CONNECTION)
{
UpdateStatus("Logging on...");
//// WAIT AGAIN 1 SEC AND CONTINUE///
//LoginCheck login = new LoginCheck(USER_NAME, PASSWORD);
if (true)//login.LOGIN_SUCESS)
{
UpdateStatus("Success!");
// SHOW THIS TEXT AND WAIT 1 SEC UNTIL SPLASH SCREEN FADE OUT//
//MessageBox.Show(login.HASH);
//opac.Interval = 12;
//opac.Start();
//opac.Tick += new EventHandler(dec);
}
else
{
//MessageBox.Show(login.HASH);
}
}
}
else
{
UpdateStatus("No user profile found.");
// ask user to register
}
}
protected bool DATABASE_CONNECTION { get; set; }
protected bool RegisteredUser { get; set; }
private void Form1_Load(object sender, EventArgs e)
{
var invoker = new MethodInvoker(CheckUser);
invoker.BeginInvoke(null, null);
}
}
正如您所看到的,我使用UpdateStatus
之类的方法为我在UI上工作,确保在UI线程上完成。您可以使用任意数量的类似方法在UI中执行其他操作,例如触发表单的淡入或其他任何内容。
你甚至不应该在UI线程之外显示消息框;通过类似的方法安全地调用那些(也用于调试,只需要Debug.WriteLine
将消息写入调试器而不是全部弹出消息框。)
答案 1 :(得分:1)
我建议您在单独的后台工作线程中执行所有操作并更新UI中的状态。这使得UI更快,应用程序可靠。
http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx
答案 2 :(得分:0)
您需要使用Invoke(),请参阅this
答案 3 :(得分:0)
public partial class SplashScreen : Form
{
bool DATABASE_CONNECTION;
bool RegisteredUser; // if user has been registered
string USER_NAME;
string PASSWORD;
double LIN_x = 0.01;
DialogResult result;
custom con = new custom();
Timer opac = new Timer();
public SplashScreen()
{
InitializeComponent(); // initalize splash screen
DatabaseStatus(); // set database connection
getUserInfo(); // get user information
showInfo(); // show app information on splash screen
}
private void UpdateStatus(string message)
{
BeginInvoke(new MethodInvoker(() => richTextBox1.Text += message + Environment.NewLine));
}
void checkUser()
{
UpdateStatus("Loading user settings...");
if (RegisteredUser)
{
UpdateStatus("User " + USER_NAME + " found." );
if (DATABASE_CONNECTION)
{
UpdateStatus("Logging on...");
LoginCheck login = new LoginCheck(USER_NAME, PASSWORD);
if (login.LOGIN_SUCESS)
{
UpdateStatus("Success! Loading " + con.AppTitle() + "...please wait");
//UpdateStatus(login.HASH); return hash string from web site
fadeSplash(); // begin fade out of form
}
else
{
UpdateStatus("There was an error logging in.");
}
}
else
{
UpdateStatus("No database connection found.");
}
}
else
{
UpdateStatus("No user found");
Reg(); // Registration form
}
}
private void fadeSplash()
{
opac.Interval = 12;
opac.Tick += new EventHandler(dec);
opac.Start();
}
private void dec(object sender, EventArgs e)
{
this.Opacity -= LIN_x;
if (this.Opacity < 0.04)
{
opac.Stop();
this.Hide();
main open = new main(); // start application
open.Show();
}
}
}
这是在MethodInvoke
期间fade方法不会触发的代码