如何将表单加载时间从一种形式减少到另一种形式

问题描述 投票:0回答:1

这是我的菜单中的代码,它在单击时创建另一个表单的实例。

private void btn_AdminReg_Click(object sender, EventArgs e)
{
    this.Hide();
    Admin_Login login = new Admin_Login(1);
    login.Show();
}

它传递一个参数来验证它将采用哪个点(相同的登录表单用于登录多个表单)

在下一个表单中,代码看起来像这样(Data是我定义的类。它具有连接字符串并从db获取数据并插入,更新,删除所有函数)

public partial class Admin_Login : MetroFramework.Forms.MetroForm
{
    int separator; // this is used to separate different logins

    public Admin_Login(int value)
    {
        InitializeComponent();
        separator = value;
    }

    //------- Legend ---------
    //if separator= 1 : AdminTerminal
    //if separator= 2 : UpdatingTerminal
    //if separator= 3 : View Registration
    //if separator= 4 : Registration
    //if separator= 5 : Reports
    //if separator= 6 : Cancel Union

    static string path = Path.GetFullPath(Environment.CurrentDirectory);
    static string dataBaseName = "Trade_Union_Registration.mdf";

    private void btn_Login_Click(object sender, EventArgs e)
    {
        if (separator == 1)
        {
            Data getTable = new Data();
            DataTable table = getTable.GetData("select  UserName,Password from SuperUser where UserName='" + txt_UserName.Text + "' and Password='" + txt_Password.Text + "'");

            if (table.Rows.Count == 1)
            {
                this.Hide();
                TerminalAdmin AdminTerminal = new TerminalAdmin();
                AdminTerminal.Show();
            }
            else
            {
                MetroFramework.MetroMessageBox.Show(this, "Invalid Username/Password please check your Username and Password and try again.", "Access Denied", MessageBoxButtons.OK, MessageBoxIcon.Error);
                txt_Password.Clear();
            }
        }
        else if (separator == 2)
        {
            Data getTable = new Data();
            DataTable table = getTable.GetData("select  UserName,Password from Admin_Table where UserName='" + txt_UserName.Text + "' and Password='" + txt_Password.Text + "'");

            if (table.Rows.Count == 1)
            {
                Data getter = new Data();
                DataTable dt = getter.GetData("select UserID from Admin_Table where UserName='" + txt_UserName.Text + "'");
                MessageBox.Show(dt.Rows[0][0].ToString());
                this.Hide();
                Updating form = new Updating(dt.Rows[0][0].ToString(), txt_UserName.Text);
                form.Show();
            }

当我运行此代码时,我的表单需要花费大量时间将一个表单加载到其他表单。怎么解决这个?

c# winforms
1个回答
1
投票

首先,我必须同意你的方法(Connacting SQL Queries,普通密码)对除了最原始的学习例子以外的所有人都是有问题的。但我要说它只是一个这样的学习例子。

显示中的任何内容都不会花费很长时间,但很少有代码丢失。我最好的猜测是你在构造函数之间的某个地方做了一些数据库查询并实际显示了Form。在这种情况下,了解Windows窗体表单的“生命周期”以及引发任何事件的顺序非常重要。不幸的是,我有问题找到像asp.net页面一样的列表。这是我能得到的最接近的:https://docs.microsoft.com/en-us/dotnet/framework/winforms/order-of-events-in-windows-forms

如果在首次显示表单后必须运行任何代码,请将其放入Form.Shown()事件中。这就是现有的目的。

总的来说,您将需要某种形式的多任务来使这种应用程序工作:数据库查询,网络操作以及较小程度的磁盘操作非常慢(与代码可以执行的大多数其他操作相比)。任何多任务/ -Threading方法都应该有效:BackgroundWorker,Threads,async ...等待模式。

如果你不这样做,你只需锁定GUI线程。对用户来说将是“没有响应”消息而不对任何鼠标操作作出反应。

我会:

  • 将一个或多个后台工作程序添加到此表单(每个数据库操作一个)。选择BackgroundWorker是因为它是学习多任务/ - 线程的一个很好的初学者工具。
  • 只能使用按钮启动后台工作人员。不要将实际DB访问代码放在这些按钮后面。如果您将DB访问代码置于后面的按钮,则在DB访问完成或超时之前,表单无法响应。
  • BackgroundWorker完成后将结果放到屏幕上。对于具有数据库访问权限的进度报告,您无能为力。

几年前,我做了一个简单的BackgroundWorker示例。报告中必须删除一些像报告这样的东西,但总的来说它仍然应该让你走上正轨:

#region Primenumbers
private void btnPrimStart_Click(object sender, EventArgs e)
{
	if (!bgwPrim.IsBusy)
	{
		//Prepare ProgressBar and Textbox
		int temp = (int)nudPrim.Value;
		pgbPrim.Maximum = temp;
		tbPrim.Text = "";

		//Start processing
		bgwPrim.RunWorkerAsync(temp);
	}
}

private void btnPrimCancel_Click(object sender, EventArgs e)
{
	if (bgwPrim.IsBusy)
	{
		bgwPrim.CancelAsync();
	}
}

private void bgwPrim_DoWork(object sender, DoWorkEventArgs e)
{
	int highestToCheck = (int)e.Argument;
	//Get a reference to the BackgroundWorker running this code
	//for Progress Updates and Cancelation checking
	BackgroundWorker thisWorker = (BackgroundWorker)sender;

	//Create the list that stores the results and is returned by DoWork
	List<int> Primes = new List<int>();
	

	//Check all uneven numbers between 1 and whatever the user choose as upper limit
	for(int PrimeCandidate=1; PrimeCandidate < highestToCheck; PrimeCandidate+=2)
	{
		//Report progress
		thisWorker.ReportProgress(PrimeCandidate);
		bool isNoPrime = false;

		//Check if the Cancelation was requested during the last loop
		if (thisWorker.CancellationPending)
		{
			//Tell the Backgroundworker you are canceling and exit the for-loop
			e.Cancel = true;
			break;
		}

		//Determin if this is a Prime Number
		for (int j = 3; j < PrimeCandidate && !isNoPrime; j += 2)
		{
			if (PrimeCandidate % j == 0)
				isNoPrime = true;
		}

		if (!isNoPrime)
			Primes.Add(PrimeCandidate);
	}

	//Tell the progress bar you are finished
	thisWorker.ReportProgress(highestToCheck);

	//Save Return Value
	e.Result = Primes.ToArray();
}

private void bgwPrim_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
	pgbPrim.Value = e.ProgressPercentage;
}

private void bgwPrim_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
	pgbPrim.Value = pgbPrim.Maximum;
	this.Refresh();

	if (!e.Cancelled && e.Error == null)
	{
		//Show the Result
		int[] Primes = (int[])e.Result;

		StringBuilder sbOutput = new StringBuilder();

		foreach (int Prim in Primes)
		{
			sbOutput.Append(Prim.ToString() + Environment.NewLine);
		}

		tbPrim.Text = sbOutput.ToString();
	}
	else 
	{
		tbPrim.Text = "Operation canceled by user or Exception";
	}
}
#endregion
© www.soinside.com 2019 - 2024. All rights reserved.