我目前正在使用XNA开发一个项目,该项目从本地SQL数据库中提取有关每个对象(每个对象将显示在屏幕上)的信息(ID、名称、文件位置等)。
我希望在单独的线程上运行我的数据库查询,以便在数据库挂起或发生其他意外事件时,渲染屏幕不会冻结。我正在使用XNA 4.0,并且该应用程序仅在Windows上运行。这是否可能,如果可能,如何实现?
我目前正在使用XNA开发一个项目,该项目从本地SQL数据库中提取有关每个对象(每个对象将显示在屏幕上)的信息(ID、名称、文件位置等)。
我希望在单独的线程上运行我的数据库查询,以便在数据库挂起或发生其他意外事件时,渲染屏幕不会冻结。我正在使用XNA 4.0,并且该应用程序仅在Windows上运行。这是否可能,如果可能,如何实现?
根本不要这样做。认真的。使用线程有很好的理由,但你的理由是虚假的:
如果数据库挂起或发生其他意外事件,渲染屏幕不会冻结
数据库不会挂起,意外事件是无法预测的。例如,当数据库不回答3分钟时,你如何应对?显示一些未知的对象屏幕吗?
var myDbThread = new Thread(()=>myDbRepo.GetRecordById<MyEntity>(idString));
myDbThread.Start();
Action myDbLambda = () => myEntityProperty = myDbRepo.GetRecordById<MyEntity>(idString);
var asyncResult = myDbLambda.BeginInvoke();
一旦asyncResult.IsComplete返回true,myEntityProperty就有了值。您还可以将其构建为Func,并使用回调来设置值(这是推荐的)。异步模型内置于BeginInvoke()/EndInvoke()方法对中,许多异常(如超时)都由线程池处理,它会简单地重新启动超时的线程。但是,您不能“放弃”并终止线程池线程,“加入”线程池线程有点棘手,如果您正在启动大量线程,则线程池将以250毫秒间隔开始它们,这可能不是处理器的最佳使用方式。
有许多使用线程池的方法;在委托在.NET编程中变得更加重要之前,在v3.5中,ThreadPool.QueueUserWorkItem是主要方法。现在,正如我所说,委托具有BeginInvoke和EndInvoke方法,允许您使用异步模型在幕后启动后台进程。在WinForms/WPF中,您还可以创建BackgroundWorker组件,它们是事件驱动的,允许您在GUI元素中监视进度和完成情况。
需要注意的一件事是,在ASP.NET中几乎从不使用后台线程是一个好主意。除非您真的知道自己在做什么,否则最好的情况是您无法获得发送到工作线程的行为结果,最坏的情况是您可能会崩溃您的站点。