在c#中,如何锁定表单
本文关键字:锁定 表单 何锁定 | 更新日期: 2023-09-27 18:06:27
我试图锁定主表单,而请等待框显示在屏幕上,但它不会工作。这就是我的困境。
我有两个表格。用户单击刷新按钮加载SQL server列表的主要表单,以及在加载列表时显示的请等待表单。在使用c#时,SQL Server线程默认是一个单独的线程,它锁住主线程以处理SQL请求。
我可以添加一个后台工作者,但是我不能更新我的组合框来显示列表作为它的UI控件。如果我使用处理程序,我的show_dialog()的请等待框将停止锁定主表单。
在主线程再次激活后,如何在没有左键队列的情况下锁定此表单?我添加了需要在用户等待时执行的代码。
public void PullServers()
{
bool ServersFound = false;
foreach (string Value in SQL.LocateSqlInstances())
{
this.cmbServer.Items.Add(Value);
ServersFound = true;
}
if (!ServersFound)
{
this.cmbServer.Items.Add(Strings.Lang("ddServerNoneFound"));
this.cmbServer.SelectedIndex = 0;
}
else
{
if (!s.empty(General.setting("SQLSERVER")))
{
this.cmbServer.Text = General.setting("SQLSERVER");
}
else
{
this.cmbServer.SelectedIndex = 0;
}
}
this.picRefreshServers.Image = Properties.Resources.Refresh;
}
public static Array LocateSqlInstances()
{
using (DataTable sqlSources = System.Data.Sql.SqlDataSourceEnumerator.Instance.GetDataSources())
{
string Servers = null;
foreach (DataRow source in sqlSources.Rows)
{
string instanceName = source["InstanceName"].ToString();
if (!s.empty(instanceName))
{
Servers += source["ServerName"].ToString() + "''" + instanceName + "[[SERVBREAK]]";
}
}
string[] ServersList = Servers.Split(new string[] { "[[SERVBREAK]]" }, StringSplitOptions.RemoveEmptyEntries);
return ServersList;
}
}
我认为您使用BackgroundWorker的方法是正确的。我发现下面的模式对我很有效。
在主表单中,需要执行以下步骤:
- 创建一个BackgroundWorker来执行长时间运行的操作。 启动BackgroundWorker
- 将等待表单显示为模态对话框。
// Step 1:
BackgroundWorker bg = new BackgroundWorker()
bg.DoWork += new DoWorkEventHandler(bg_DoWork);
bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);
// Step 2:
bg.RunWorkerAsync();
// Step 3:
waitingForm = new WaitingForm();
waitingForm.ShowDialog();
如你所知,你不能从bg_DoWork
处理程序更新UI,因为它不在UI线程上运行。因此,只需在这里获取所需的数据,并使用e.Result参数将其传递给bg_RunWorkerCompleted
处理程序。
private void bg_DoWork(object sender, DoWorkEventArgs e)
{
Array servers = SQL.LocateSqlInstances();
e.Result = servers;
}
bg_RunWorkerCompleted
在UI线程上运行,所以在这里更新控件是安全的。在这里,您应该关闭等待表单,然后更新您的UI。
private void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Close the Waiting form.
waitingForm.Close();
// Retrieve the result of bg_DoWork().
Array servers = e.Result as Array;
bool ServersFound = false;
foreach (string Value in servers)
{
this.cmbServer.Items.Add(Value);
ServersFound = true;
}
if (!ServersFound)
{
this.cmbServer.Items.Add(Strings.Lang("ddServerNoneFound"));
this.cmbServer.SelectedIndex = 0;
}
else
{
if (!s.empty(General.setting("SQLSERVER")))
{
this.cmbServer.Text = General.setting("SQLSERVER");
}
else
{
this.cmbServer.SelectedIndex = 0;
}
}
this.picRefreshServers.Image = Properties.Resources.Refresh;
}