- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
背景:
我有一个使用LWJGL实现的3D引擎,主要用于渲染大型“世界”-地形,植被,动画生物,天气,昼/夜循环等。该引擎管理渲染所需的资源,例如各种纹理,网格,模型等
当玩家在这个世界中航行时,引擎会缓存不再需要的各种类型的数据丢弃/释放资源,并按需加载/缓存新需要的数据。这由一组执行I / O任务(加载图像,加载新的地形“块”,构建模型网格等)的后台线程以及要在OpenGL上下文中执行的任务队列(分配一个新的)来处理。纹理,将数据上传到VBO,删除纹理等)。
当前设计:
除了具有依赖项的任务以外,所有这些都很好地工作。我将通过一个示例进行说明-假设引擎需要将新纹理应用于场景中的对象。
这包括以下步骤:
从文件系统加载纹理图像(I / O后台任务)
在GPU上分配纹理(OpenGL上下文任务)
将图像上传到纹理(OpengL)
将纹理附加到对象的材质上(OpenGL,不是真的,但是避免了渲染问题)
这里有一些问题需要解决:
理想情况下,我希望这些步骤(或任务)是原子性的并且可重复使用,例如,引擎需要为系统的其他几个部分加载图像-代码完全相同,因此可以(并且应该)封装并重新使用-用过的。
其中一些可以并行运行(例如,加载图像并分配
纹理),其中一些必须是连续的,例如无法上传
图片,直到我们加载它并分配了纹理。
有些步骤与先前的步骤具有“资源依赖性”,例如在
特别是上传步骤需要分配的纹理ID和
图片。
前两个结果相对简单明了,最后一个是我正在努力解决的问题-我似乎无法想出一个像样的设计来允许将可重用和相对原子的任务在相互关联时链接在一起-任务依赖关系。
一些伪代码:
界面Task实现了Runnable {
TaskQueue getQueue();
}
//通用的加载图片任务
LoadImageTask类实现了任务{
私有最终String路径;
私有BufferedImage图像;
公共LoadImageTask(字符串路径){
this.path =路径;
}
TaskQueue getQueue(){返回TaskQueue.BACKGROUND; }
公共无效run(){
//从给定位置加载图像
}
}
//将图像上传到给定的纹理
类UploadTextureTask实现任务{
私有BufferedImage图像;
私有Texture纹理;
...
TaskQueue getQueue(){返回TaskQueue.RENDER_THREAD; }
公共无效run(){
texture.buffer(image);
}
}
//上面概述的方案的示例任务管理器
类示例扩展TaskManager {
...
//加载纹理图像
最后的LoadImageTask loadImage = new LoadImageTask(...);
add(loadImage);
//分配纹理
最后的AllocateTextureTask分配= ...
添加(分配);
//上传纹理图片
最终UploadTextureTask upload = ...
添加(上传,loadImage,分配);
}add
中的TaskManager
方法在后台将任务注册到相关队列中。当每个任务完成时,经理会收到通知。当所有当前任务完成时(在这种情况下为loadImage
和allocate
),管理器将启动序列中的下一个任务。
请注意,对add
任务的最后一个upload
调用告诉管理员,它依赖于load
和allocate
任务。
问题:
问题是当这些类没有以任何方式耦合时,如何将“生产者”任务(例如LoadImageTask
)返回的“资源”传递给“消费者”任务(例如UploadTextureTask
)?
一种(垃圾)方式是拥有一些自定义代码,该代码在任务完成时调用loadImage.getImage()
并将其使用uploadTask.setImage()
传递给“链”,但是如果必须粗略地编写该代码,这几乎使整个方法变得毫无意义。每个用例都使用相同的任务管理代码。
我尝试使用通用的getter / setter方法定义消费者和生产者接口,并链接具有正确匹配的数据类型的从属任务,但是如果一个任务消耗了多个资源(如上载任务所做的那样),则这种方法就会失效。
我还考虑过使用Future
和Callable
(后台任务队列始终使用Executor
线程池),但它们的使用方向实际上是阻塞整个线程,而不是资源管理本身。该系统中的任务数可以是数千个,其中大多数是当前正在运行或正在排队的待处理任务。阻止尚未开始的任务似乎毫无意义。知道未来何时完成的唯一方法(?)是调用isDone
,这意味着轮询完成任务的另一层复杂性。
我在这里以及在OpenGL开发人员和游戏网站上都研究了这个问题,但是还没有遇到任何好的设计-它们似乎只是由剪切和粘贴代码或某种共享状态(通常是地图)组成,其中包含许多到处都是讨厌的演员。也许我没有搜索正确的术语?也许我的整个方法都是垃圾?
有没有人实施或遇到过类似的事情?任何建议,批评,指点都是欢迎的。 (对墙贴文本表示歉意)
最佳答案
Java 8中的一些新功能似乎可以完全解决此类问题,例如CompletableFuture
,它使用Executor
,Runnable
任务等与上述现有设计很好地集成在一起。
关于java - 处理后台消费者/生产者任务的设计或模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23542776/
从 0 开始搭建一套后台管理系统,成本巨大,所以都会选择一套成熟的组件库,基于此,再堆叠业务逻辑。我们公司的组件库基于 Ant Design。Ant Design 包含一套完整的后台解决方案,不仅
在我的 IOS 应用程序中,我有一个标记为 retain 的 NSDate* 属性 当我的应用程序再次激活时,属性值已被释放。 我是否误解了属性和内存管理的工作原理,我该如何防范? 最佳答案 很明显,
我有一个使用 BackgroundWorker 组件的示例 WinForms 应用程序。它工作正常,但是当我点击 Cancel 按钮取消后台线程时,它并没有取消线程。当我点击 Cancel 按钮调用
我目前正在开发一个应用程序,该应用程序在启动时会对服务器执行 ping 操作,该服务器会为每个连接的设备返回一个唯一标识符。设备每 5 秒从服务器检索另一页以获取一组不同的数据。这个唯一的 ID 可以
我正在开发一个应用程序,当它通过主页按钮在后台按下时,计时器应该启动,当应用程序返回前台并且计时器已经过了一定时间时,应该是执行。 我的问题是 当我的应用程序转到背景/前景? 是否有特殊的方法或其他技
我有 map View ,其中几乎没有 MKPointAnnotation。 一切正常,但是, View 的 MKPoiintAnnotation 的“背景”是“不可见的”,因此不是很“可见”。 我想
我在 iOS 中开发广告数据应用程序。我的应用程序广告数据在前台很好。但我想在 ios 后台宣传信标数据。我设置了背景外设设置。和广告数据 advertisingData = [CBAdvertise
如果我有一组操作,我想根据特定条件在后台工作程序中运行,例如,我有 10 个条件 if(a) BackgroundWorker doA = new backgroundworker() if(
我想独立运行一个函数。从我调用的函数中,我想在不等待其他函数结束的情况下返回。 我试过用 threadind,但这会等待,结束。 thread = threading.Thread(target=my
我想在用户在线时立即执行一些任务,即使他在后台也是如此。我正在使用 Reachability 类来检查互联网。但是当我在后台时,这个类没有通知我。我知道有人早些时候问过这个问题,但没有找到任何解决方案
我在后台播放文本转语音时出现间歇性(哎呀!)问题,由 Apple Watch 触发。我已经正确设置了后台模式、AVSession 类别和 WatchKitExtensionRequest 处理程序。
我有一个相当复杂的程序,所以我不会在这里转储整个程序。这是一个简化版本: class Report { private BackgroundWorker worker; public
我有一个任务在 backgroundworker 中运行。单击开始按钮,用户将启动该过程,并获得一个取消按钮来取消处理。 当用户点击取消时,我想显示一个消息框“进程尚未完成,你想继续吗”。 这里我希望
我有一个按以下方式编码的脚本。我想将它作为后台/守护进程运行,但是一旦我启动脚本,如果我关闭它从程序运行的终端窗口终止。我需要做什么来保持程序运行 loop do pid = fork do
我正在制作一个使用 ActivityRecognition API 在后台跟踪用户 Activity 的应用,如果用户在指定时间段(例如 1 小时)内停留在同一个地方,系统就会推送通知告诉用户去散步.
当尝试使用 URLSession 的 dataTaskPublisher 方法发送后台请求时: URLSession(configuration: URLSessionConfiguration.ba
当我编译这段代码时,我得到了他的错误,对象引用设置为null,错误位置在Dowork中,argumenttest.valueone = 8; public partial class Form1 :
有什么方法可以使用最小化或不活动的应用程序吗?我可以打开我的应用程序,然后打开并使用另一个应用程序,然后按一个按钮来激活我的程序吗? 例如,打开我的应用程序,打开 Safari,按下按钮(F1 或任何
我的具体要求是一个在后台运行的应用程序,被通知显示器即将进入休眠状态或者设备已经或即将达到空闲超时 - 然后唤醒并执行一些(简短的)一段代码。 我在这里找到了有关应用程序被置于后台或暂停的通知的引用:
我有一个 LSUIElement 设置为 1 的应用程序。它有一个内置编辑器,因此我希望该应用程序在编辑器打开时出现在 Cmd+Tab 循环中。 -(void)stepIntoForegrou
我是一名优秀的程序员,十分优秀!