Closed sgf closed 4 months ago
Your screenCaptureService
is only a local and will be collected by the garbage collector at some point after the 'Form1_Load' has finished, which causes it to be disposed.
You have to keep it alive (for example by storing it the same way as the screenCapture
).
I thought that generally speaking, unmanaged objects should need to be released manually. Moreover, GC should scan the reference and it should not be released. However, thanks for supporting the problem. I'll go ahead and give it a try.
Moreover, GC should scan the reference and it should not be released.
yes, and that is the problem in your case - you don't keep a reference to it. the only one you have is the local that gets released once the method exits.
yes, and that is the problem in your case - you don't keep a reference to it. the only one you have is the local that gets released once the method exits.
I originally thought the code below would form an indirect reference.
IScreenCaptureService screenCaptureService = new DX9ScreenCaptureService();
IEnumerable<GraphicsCard> graphicsCards = screenCaptureService.GetGraphicsCards();
IEnumerable<Display> displays = screenCaptureService.GetDisplays(graphicsCards.First());
screenCapture = screenCaptureService.GetScreenCapture(displays.First());
In fact, there should be indirect references internally, otherwise no error will be reported, which means that the screenshot process depends on screenCaptureService. However, this reference relationship was not scanned by the GC, so screenCaptureService was released.
This is indeed the problem, thank you for your guidance.
In fact, there should be indirect references internally, otherwise no error will be reported, which means that the screenshot process depends on screenCaptureService. However, this reference relationship was not scanned by the GC, so screenCaptureService was released.
no, that's not true here. It's quite the opposite. The ScreenCaptureService manages all the screen captures and therefore keeps references to them (not the other way around). When the ScreenCaptureService is disposed (which also happens when it's collected) it actively cleans up all the ScreenCaptures it manages (since it can't be sure that you're still able to do so once it's gone, you might not have a reference to the ScreenCapture itself).
I mean backreferences are also references. Logically speaking, GC should not distinguish between forward and reverse.
Of course, I'm not very good at writing low-coupling code. Therefore, I probably encounter this situation very rarely.😂
System.ObjectDisposedException: Cannot access a disposed object. Object name: 'ScreenCapture.NET.DX9ScreenCapture'. at ScreenCapture.NET.AbstractScreenCapture`1.CaptureScreen() at WinFormsApp1.Form1.timer1_Tick(Object sender, EventArgs e) in E:\MySrc\tmvur\WinFormsApp1\WinFormsApp1\Form1.cs:line 73
timer1.Intval=100;//100ms
There will be no errors in the first few times, but after about 8 ticks, errors will appear.