在用户界面中,我需要用户通过网络从所有可用实例中选择SQL服务器。我使用一个按钮让用户单击以显示服务器。单击按钮大约需要25秒才能显示列表。我正在考虑在加载页面时准备好服务器列表。因此,当用户单击按钮时,列表已准备就绪。但是,它在页面加载之前就会卡住。 remoteSqlServers用于ItemSource。
internal static ObservableCollection<string> remoteSqlServers = GetRemoteSqlServers().Result;
public static async Task<ObservableCollection<string>> GetRemoteSqlServers()
{
var SqlServers = await Task<ObservableCollection<string>>.Run(() =>
{
return new SqlEnumerationHelper().SqlEnumerateRemote();
}).ConfigureAwait(false);
return SqlServers;
}
我将其更改为低于它在加载之前不会卡住,但仍需要几秒钟。似乎异步操作起作用并且不知道为什么。
public static ObservableCollection<string> remoteSqlServers = new ObservableCollection<string>();
public GetSqlViewModel()
{
...
remoteSqlServers = GetRemoteSqlServers().Result;
...
}
public static async Task<ObservableCollection<string>> GetRemoteSqlServers()
{
var SqlServers = await Task<ObservableCollection<string>>.Run(() =>
{
return new SqlEnumerationHelper().SqlEnumerateRemote();
}).ConfigureAwait(false);
return SqlServers;
}
这是SqlEnumerateRemote:
public ObservableCollection<string> SqlEnumerateRemote()
{
ObservableCollection<string> sqlServerNames = new ObservableCollection<string>();
LogHelper.log("SqlEnumerationHelper:SqlEnumerateRemote", "Starting");
try
{
//Make an initial call to the sql browser service to wake it up
using (DataTable sqlSources = SqlDataSourceEnumerator.Instance.GetDataSources())
{
//There are issues with SqlDataSourceEnumerator, that it doesn't always return all sql instances
}
SqlDataSourceEnumerator instance = SqlDataSourceEnumerator.Instance;
System.Data.DataTable dt = instance.GetDataSources();
DataRow[] rows = dt.Select(string.Empty, "ServerName asc");
if (rows.Length > 0)
{
foreach (DataRow dr in rows)
{
string serverName = dr["ServerName"].ToString();
string instanceName = dr["InstanceName"].ToString();
if (instanceName.Length > 0)
serverName += "\\" + instanceName;
sqlServerNames.Add(serverName);
}
}
LogHelper.log("SqlEnumerationHelper:SqlEnumerateRemote", "Ending");
}
catch (Exception e)
{
LogHelper.log("SqlEnumerationHelper:SqlEnumerateRemote", "SqlDataSourceEnumerator.GetDataSources and assoc processing failed" + e.Message);
}
return sqlServerNames;
}
答案 0 :(得分:0)
编辑:对于这个问题,这个答案不是正确的,尽管我会为偶尔的路人留下它。
尝试一下BackgroundWorker,它们非常适合从繁琐的UI中解脱出来。
using System.Collections.ObjectModel;
using System.ComponentModel;
internal static ObservableCollection<string> remoteSqlServers;
public BackgroundWorker Sync = new BackgroundWorker();
public MyControl()
{
InitializeComponent();
remoteSqlServers = new ObservableCollection<string>();
Sync.DoWork += Sync_DoWork;
Sync.RunWorkerCompleted += Sync_RunWorkerCompleted;
Sync.WorkerSupportsCancellation = true;
Sync.RunWorkerAsync();
}
private void Sync_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
if ((worker.CancellationPending == true))
{
e.Cancel = true;
}
else
{
return SqlEnumerationHelper().SqlEnumerateRemote();
}
}
private void Sync_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ((e.Cancelled == false))
{
if (e.Result != null)
{
remoteSqlServers = (SqlServers)e.Result;
}
}
}
答案 1 :(得分:0)
第二轮!
我不确定SqlEnumerateRemote()
到底是什么,但这不应该挂起你的代码,因为它的作用很神奇。
当您尝试加载remoteSqlServers
时,它正在等待您的操作在初始化之前完成。
初始化,然后像这样加载:
internal static ObservableCollection<string> remoteSqlServers = new ObservableCollection<string>();
public MyControl()
{
InitializeComponent();
GetRemoteSqlServers();
//so on and so forth
}
public static async Task GetRemoteSqlServers()
{
foreach (var item in (await Task.Run(() =>
{ return new SqlEnumerationHelper().SqlEnumerateRemote(); })))
{
remoteSqlServers.Add(item);
}
}