如何使用线程在XNA中运行数据库查询

本文关键字:运行 数据库 查询 XNA 何使用 线程 | 更新日期: 2023-09-27 17:59:06

我目前正在用XNA开发一个项目,该项目从本地SQL数据库中提取关于我的每个对象(每个对象都将显示在屏幕上)的信息(ID、名称、文件位置等)。

我想在一个单独的线程上运行我的数据库查询,这样在数据库挂起或发生其他不可预见的事件时,呈现的屏幕就不会冻结。我使用的是XNA 4.0,该应用程序将只在windows上运行这可能吗?如果可能,怎么做

如何使用线程在XNA中运行数据库查询

有许多可用选项。一般来说,您需要在单独的线程中运行查询。你可以使用

  1. 线程池

    • 队列用户工作项
    • 任务
    • 后台工作人员
    • 对数据库的异步调用
    • 并行调用
  2. 在此处和此处手动创建线程

我将从线程池开始,看看它是如何工作的,专用的手动线程在内存管理和重用方面并不那么健壮。

根本不做。认真地使用线程有很好的理由,但你的理由是假的:

如果数据库挂起或发生其他不可预见的事件,则呈现的屏幕不会冻结

数据库不会挂起,不可见事件就是不可见事件。例如,你如何应对数据库在3分钟内没有应答的情况?显示包含未知对象的屏幕?

"最好"是什么意思?有很多方法可以使用线程,它们都有优点和缺点。

显式地声明一个新线程并启动它,可以最直接地控制该线程的执行状态:

var myDbThread = new Thread(()=>myDbRepo.GetRecordById<MyEntity>(idString));
myDbThread.Start();

现在,只要你有一个对myDbThread的引用,你就可以中止它,暂停它,加入它,等等。但是,控制带来了责任;您必须管理自己创建的线程。

对于大多数并行任务,建议使用ThreadPool。然而,你失去了一些控制:

Action myDbLambda = () => myEntityProperty = myDbRepo.GetRecordById<MyEntity>(idString);
var asyncResult = myDbLambda.BeginInvoke();

一旦asyncResult.IsComplete返回true,myEntityProperty就具有值。您也可以将其构建为Func,并使用回调来设置值(建议这样做)。异步模型内置在BeginInvoke()/EndInvoke(。然而,你不能"放弃"并终止线程池线程,在线程池线程上"加入"有点棘手,如果你启动了很多线程,线程池会以250毫秒的间隔启动它们,这可能不是处理器的最佳用途。

有很多方法可以使用ThreadPool;在委托对v3.5中的.NET编程变得更加重要之前,ThreadPool.QueueUserWorkItem是主要方法。现在,正如我所说的,委托具有BeginInvoke和EndInvoke方法,允许您使用后台构建的异步模型启动后台进程。在WinForms/WPF中,您还可以创建事件驱动的BackgroundWorker组件,允许您在GUI元素中监控进度和完成情况。

有一件事需要注意;在ASP.NET中使用后台线程实际上从来都不是一个好主意。除非你真的知道自己在做什么,否则最好的情况是你不会得到发送到工作线程的行为的结果,最坏的情况是,你可能会尝试破坏你的网站。