1

在使用 DirectX 渲染 3D 组件的程序中,我使用了一个专用的渲染线程,如果我调用DispatcherQueueController::CreateOnDedicatedThread()显然会创建该线程。需要渲染的内容受到主线程上执行的操作的影响,这就是我使用scoped_lock来同步访问的原因。

创建渲染线程的代码和在其中运行的代码如下所示:

void MyCustomView::StartRenderingLoop()
{
  if(!_isRenderLoopRunning)
  {
    _renderLoopController = DispatcherQueueController::CreateOnDedicatedThread();
    _isRenderLoopRunning  = _renderLoopController.DispatcherQueue().TryEnqueue([this]()
    {
      while(_isRenderLoopRunning)
      {
        Concurrency::critical_section::scoped_lock lock(_criticalSection);

        if(_renderer->Render())
        {
          Present();
        }

        // Halt the thread until the next vblank is reached.
        // This ensures the app isn't updating and rendering faster than the display can refresh,
        // which would unnecessarily spend extra CPU and GPU resources. This helps improve battery life.
        _dxgiOutput->WaitForVBlank();
      }
    });
  }
}

C++ 头文件中的关联成员变量如下所示:

private:
  concurrency::critical_section _criticalSection;
  winrt::Microsoft::UI::Dispatching::DispatcherQueueController _renderLoopController{ nullptr };
  bool _isRenderLoopRunning  = false;

为了停止渲染线程,3D 组件的析构函数包含以下代码:

MyCustomView::~MyCustomView()
{
  _isRenderLoopRunning = false;
  _renderLoopController.ShutdownQueueAsync();
}

当 3D 组件被破坏时,Visual C++ 运行时会抛出一个如下所示的断言:

Debug Assertion Failed!

Program: MyAppPackage\CONCRT140D.dll
File: d:\agent\_work\18\s\src\vctools\crt\crtw32\concrt\rtlocks.cpp
Line: 1001

Expression: Lock was destructed while held

我可以获得的调用堆栈如下所示:

concrt140d.dll!Concurrency::critical_section::~critical_section() + 79 bytes    Unknown
MyCustomComponents.dll!winrt::MyCustomComponents::implementation::BaseView::~BaseView() C++
MyCustomComponents.dll!winrt::implements<winrt::MyCustomComponents::implementation::MyCustomView,winrt::MyCustomComponents::MyCustomView,winrt::MyCustomComponents::implementation::BaseView,winrt::no_module_lock>::~implements<winrt::MyCustomComponents::implementation::MyCustomView,winrt::MyCustomComponents::MyCustomView,winrt::MyCustomComponents::implementation::BaseView,winrt::no_module_lock>()   C++
MyCustomComponents.dll!winrt::MyCustomComponents::implementation::MyCustomView_base<winrt::MyCustomComponents::implementation::MyCustomView,winrt::MyCustomComponents::implementation::BaseView>::~MyCustomView_base<winrt::MyCustomComponents::implementation::MyCustomView,winrt::MyCustomComponents::implementation::BaseView>() C++
MyCustomComponents.dll!winrt::MyCustomComponents::implementation::MyCustomView::~MyCustomView() Line 32 C++

我很难理解断言是否Lock was destructed while held指向实际问题,或者忽略它是否安全。如果这是一个实际问题,我将如何正确解决它?

4

0 回答 0