当我尝试连接到不存在的实例时,UI会在我的应用程序中锁定 我尝试过使用新线程,但这似乎不起作用
//从主类调用
Dispatcher.BeginInvoke(new Action(
() => Timedtask(instance, database)));
//Method
public void Timedtask(string instance, string database)
{
Timer.Start();
Timer.Tick += delegate
{
if (!TimedTask.timer_Tick(instance, database))
{
Dispatcher.CurrentDispatcher.Invoke(Stopped);
}
};
}
// Try an open connection
using (var con1 = new SqlConnection
{
ConnectionString = @"Data Source=" + instanceName1 + ";Integrated Security=SSPI;" +
"MultipleActiveResultSets=true;"
})
{
//more code
con1.Open();
//more code
}
答案 0 :(得分:8)
Dispatcher.BeginInvoke
将回调放回UI线程,而不是后台线程。因此,您的所有操作都在UI线程上运行。因此锁定你的用户界面。
使用Task
或BackgroundWorker
委托后台线程进行呼叫。请注意,任何GUI组件都无法从后台线程进行修改,因此您需要使用Dispatcher.Invoke
或Dispatcher.BeginInvoke
将其复制回UI线程。
Task.Factory.StartNew(() => { Timedtask(instance, database) });
或强>
如果使用.Net 3.5,则可以使用backgroundWorker:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (s, e) => { Timedtask(instance, database); };
worker.RunWorkerAsync();
答案 1 :(得分:4)
我喜欢使用BackgroundWorkers
设定:
private BackgroundWorker bw;
bw.DoWork += bw_DoWork;
bw.RunWorkerCompleted += bw_WorkCompleted;
实施这些方法:
protected void bw_DoWork(object sender, DoWorkEventArgs e)
{
//Do database stuff here
}
protected void bw_WorkCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//This is called when the background worker is done. This is where you can update the UI
}
然后启动工人:
bw.RunWorkerAsync();
答案 2 :(得分:2)
你可以使用任务
Task.Factory.StartNew(() =>
{
using (var con1 = new SqlConnection
{
ConnectionString = @"Data Source=" + instanceName1 + ";Integrated Security=SSPI;" +
"MultipleActiveResultSets=true;"
})
{
//more code
con1.Open();
//more code
}
});
答案 3 :(得分:0)
您可以使用BackgroundWorker
解决此类问题。
在这里,您可以在BackgroundWorker
应用程序中找到有关WPF
的使用和实施的详细有用信息:How to use WPF Background Worker
答案 4 :(得分:0)
TPL
优于BackgroundWorker
。尝试使用TPL(Task Parrel Liaberary)
,因为Task Parellel类比BackgroundWorker
更好。它自然支持嵌套(父/子任务),使用新的取消API,任务延续等。
请在 Stephen Cleary 的以下链接中打开“报告任务进度”: