smourier / DirectN

Direct interop Code for .NET Framework, .NET Core and .NET 5+ : DXGI, WIC, DirectX 9 to 12, Direct2D, Direct Write, Direct Composition, Media Foundation, WASAPI, CodecAPI, GDI, Spatial Audio, DVD, Windows Media Player, UWP DXInterop, WinUI3, etc.
MIT License
311 stars 28 forks source link

`VerticalBlankTicker` throws unknown error 0xc01e0006 when the monitor is off #29

Closed d2phap closed 2 years ago

d2phap commented 2 years ago

Hi @smourier

As the title says, this error causes by line 122.

To reproduce

  1. Run the app
  2. Close laptop lid / turn off monitor
  3. See error

But the question is, should the ticker sleep while the monitor is off instead of throw the exception. With this way, the ticker can auto-recover again.

https://github.com/smourier/DirectN/blob/56de709b44352dbe3ee4bbccb2f301eb7fca40f8/DirectN/DirectN/Extensions/VerticalBlankTicker.cs#L91-L123

My suggestion:

do
{
  status = D3DKMTWaitForVerticalBlankEvent(ref we);
  if (status == 0)
  {
    // no change
    // ...
  }
  else
  {
    // the monitor is off, we put the thread into sleep to recover the VBTicker later
    Thread.Sleep(1000);
  }

  if (_stop)
    break;
}
while (true);
smourier commented 2 years ago

Hi,

Good remark. What I've done is added a WaitError event to the class so you can handle any error the way you like, for example:

var vbt = new VerticalBlankTicker();
vbt.Tick += ...
vbt.WaitError += Vbt_WaitError;
vbt.Start();

...

private static void Vbt_WaitError(object sender, VerticalBlankTickerErrorEventArgs e)
{
  if (e.Error == unchecked((int)0xc01e0006))
  {
      Console.WriteLine("error! wait & continue...");
      Thread.Sleep(1000);
      e.Handled = true;
  }
}
d2phap commented 2 years ago

Awesome! Thanks for creating this library. I successfully port the C++ Direct2D project to use your WicNet and parts of DirectN in my software ImageGlass v9.0 beta 2!