【问题标题】:How to run a process in the background of an HoloLens application?如何在 HoloLens 应用程序的后台运行进程?
【发布时间】:2020-08-11 02:33:12
【问题描述】:

目前,我的代码可以从 hololens 的本地内存中加载和渲染一个 obj 文件。但是,在此过程中,应用程序会完全暂停,这可能需要几秒钟的时间,具体取决于网格的大小和复杂性。 由于有人可能怀疑应用程序在此期间崩溃了,因此我想将渲染移至后台进程并保持主线程处于活动状态。

当前行为:

在加载和渲染 obj 文件时,应用程序会暂停几秒钟。

期望的行为:

网格的加载和渲染是在后台进程中计算的,并且应用程序保持活动状态。

代码sn-p:

public class FileExplorer: MonoBehaviour {
    private FileOpenPicker openPicker;

    public void OpenExplorer() {
        UnityEngine.WSA.Application.InvokeOnUIThread(() = >OpenFileAsync(), false);
        LoadModelFromFile();
    }

    private async void OpenFileAsync() {
        openPicker = new FileOpenPicker();
        openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
        openPicker.FileTypeFilter.Add(".obj");

        StorageFile file = await openPicker.PickSingleFileAsync();
        if (file != null) {
            path = file.Path;
        }
    }

    public void LoadModelFromFile() {
        Mesh newMesh = Instantiate(GetComponent < ObjFileLoader > ().LoadModel(path)) as Mesh;
    }
}

注意事项:

  • 我已经删除了我认为不必要的所有内容,如果有一些问题我可以将其添加到现有代码中
  • LoadModel(path) 返回一个网格
  • 我试图让它类似于异步 OpenFileAsync 函数,但这只会导致几个错误
  • 我读过异步(Async and Await;Don't Block on Async Code,但不太明白
  • 也许有人可以提示我,我应该使用什么值await

如果有人遇到类似的问题并且可以帮助我解决这个问题或者可以给我一个提示,我将非常感激。

【问题讨论】:

    标签: c# asynchronous uwp async-await hololens


    【解决方案1】:

    我认为您正在寻找的是这样的东西。

    public async Task OpenExplorer() {
        UnityEngine.WSA.Application.InvokeOnUIThread(async() => await OpenFileAsync(), false);
        await Task.Run(LoadModelFromFile);
    }
    

    不过,我对您的建议是阅读有关 Async 和 Await 的更多信息,因为根据您的情况,上述代码可能不遵循最佳实践并且可能很危险。

    主要的是 Async 和 Await 不是关于多线程代码的。 Async 和 Await 是关于更有效地使用单个线程。代码中有两个主要瓶颈,IO 和 CPU,async await 可以很好地处理 IO 瓶颈,因为它可以在等待磁盘操作或等待 Web 请求时释放线程来处理其他事情(它们是不消耗任何线程)。

    如果你让一个方法异步,但你唯一要做的就是让它异步启动很多长时间运行的代码到不同的线程,除非你释放的线程是UI 线程,但您确定这一点的唯一方法是您是否在 UI 线程上。

    因此,仅当您需要释放 UI 线程时,才从 UI 上下文中执行 await Task.Run... 之类的操作。在其他任何地方,仅将方法标记为异步,如果它们是纯粹的 IO 相关异步,例如 File.ReadAsync 或其他不消耗任何额外线程的方法。

    【讨论】:

    • 首先感谢您的详细解答,非常感谢。根据建议,我将阅读更多关于 Async 和 Await 的内容。如果它不能按计划工作,我想问一下我是否可以尝试另一种方法?
    • 如果您在 UI 线程上花费大量时间,那么您所能做的就是在不同的线程上运行长时间运行的代码。 Async 和 await 使其易于处理,因为它会自动捕获 UI 上下文,因此当您的后台任务完成时,它将自动在 UI 线程上继续,但您也可以使用 ContinueWith 或使用事件来传达在后台线程上完成的工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-20
    • 1970-01-01
    • 2021-06-26
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多