在我的WPF应用程序中,我需要在后台执行数据库操作以使UI更具响应性。 我正在使用BackgroungWorker类,但由于它在不同于UI的线程上运行,我无法将参数传递给数据库查询。这些值来自UI控件。在WPF应用程序的后台执行数据库操作?
任何人都可以请帮我解决这个问题,或者建议其他方式来做数据库操作,同时使UI响应。
谢谢
在我的WPF应用程序中,我需要在后台执行数据库操作以使UI更具响应性。 我正在使用BackgroungWorker类,但由于它在不同于UI的线程上运行,我无法将参数传递给数据库查询。这些值来自UI控件。在WPF应用程序的后台执行数据库操作?
任何人都可以请帮我解决这个问题,或者建议其他方式来做数据库操作,同时使UI响应。
谢谢
如果不使用,你可以用Dispatcher.BeginInvoke方法工作BackgroungWorker类的。实际上,如MSDN所指定的:
BeginInvoke是异步的;因此,控件在被调用后立即返回给调用对象。 在WPF中,只有创建DispatcherObject的线程可以访问该对象。例如,从主UI线程分离出的后台线程无法更新在UI线程上创建的Button的内容。为了让后台线程访问Button的Content属性,后台线程必须将工作委托给与UI线程关联的Dispatcher。这是通过使用Invoke或BeginInvoke完成的。 Invoke是同步的,BeginInvoke是异步的。该操作将在指定的DispatcherPriority中添加到Dispatcher的事件队列中。
Here一篇很好的文章,解释了如何使用Dispatcher类。
我认为BackgroundWorker是工作的正确工具。当您创建BackgroundWorker时,您可以为DoWork
事件指定事件处理程序。 DoWorkEventArgs
对象上有一个属性,名为Arguments
,它是通过调用RunWorkerAsync
启动BackgroundWorker时传入的对象。您可能需要创建一个辅助类来处理需要传递的参数,但这应该很容易。喜欢的东西
助手类:
public class WorkerArgs
{
public string Arg1 {get;set;}
public object Arg2 {get;set;}
public int Arg3 {get;set;}
}
背景工人:
BackgroundWorker worker = new BackgroundWorker();
// Hook up DoWork event handler
worker.DoWork += (sender, e) => {
WorkerArgs args = e.Arguments as WorkerArgs;
// ... Do the rest of your background work
};
// Create arguments to pass to BackgroundWorker
WorkerArgs myWorkerArgs = new WorkerArgs {Arg1 = "Foo", Arg2 = new Object(), Arg3 = 123 };
// Start BackgroundWorker with arguments
worker.RunWorkerAsync(myWorkerArgs);
在你的情况,你会从你的UI控件填充值的辅助类对象。
从主UI线程分离出的后台线程无法更新在UI线程上创建的控件的内容。 – gliderkite
@gliderkite OP要求一种将参数传递给UI的方法,这可以按照描述完成。根据这篇文章http://stackoverflow.com/a/2806824/371298在UI线程上创建Background worker意味着RunWorkerCompleted事件在UI线程上引发,并且可以在没有交叉线程异常的情况下访问控件。 –