我正在尝试锁定主表单,而屏幕上显示请稍候框,但它无法正常工作。这是我的困境。
我有2个表格。用户单击刷新按钮以加载SQL Server列表的主窗体,以及在加载列表时显示的Please wait窗体。默认情况下,SQL Server线程在使用C#时是一个单独的线程,它会锁定主线程以处理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;
}
}
答案 0 :(得分:0)
我认为你使用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;
}