Преобразование текстуры Direct2D в поток памяти приводит к сбою приложения

Я пытаюсь подключить Directx11 IDXGISwapChain.Present для получения снимков экрана с использованием библиотеки Direct3DHook и EasyHook. Я думаю, что Direct3DHook написан для одиночных скриншотов, и я пытаюсь расширить его, чтобы получить поток скриншотов. После первых нескольких снимков экрана приложение хоста получает исключение при случайном стеке рендеринга.

Я могу выделить ошибку в следующем коде в файле DXHookD3D11.cs:

using (MemoryStream ms = new MemoryStream())
{
    // This line crashes the main program, removing this makes the program not crash               
    res = Texture2D.ToStream(textureDest.Device.ImmediateContext, textureDest, ImageFileFormat.Bmp, ms).Code;
    if (res != 0)
    {
        // this debugmessage never gets printed
        this.DebugMessage("PresentHook: ERror in Tostream " + res.ToString());
    }
    .......                                    
}

1 ответ

Решение

Я думаю, что нашел ошибку. Direct3DHook использует пул потоков для запуска приведенного выше кода.

ThreadPool.QueueUserWorkItem(delegate


                            {

                                
                               using (MemoryStream ms = new MemoryStream())


                                {


                                    Texture2D.ToStream(textureDest.Device.ImmediateContext, textureDest, ImageFileFormat.Bmp, ms);

                                    SendResponse(ms, requestId);


                                    this.DebugMessage("PresentHook: Send response time: " + (DateTime.Now - startSendResponse).ToString());


                                 }


                                 // Free the textureDest as we no longer need it.


                                textureDest.Dispose();


                                 textureDest = null;


                             });

Но вызов Texture.ToStream должен быть однопоточным, потому что внутри он, вероятно, выдает вызов GetRenderTarget, который является однопоточным и вызывает исключение, если два вызова запускаются асинхронно. Я удалил вызов ThreadPool, и он работал нормально.

Другие вопросы по тегам