-
Notifications
You must be signed in to change notification settings - Fork 289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
two concurrent CanvasBitmap.LoadAsync will generate "The component cannot be found. (Exception from HRESULT: 0x88982F50)" #805
Comments
@jtorjo - what overload did you use? If you used the file name overload, try the stream overload. The error is a WIC error which usually occurs if it can't find a suitable decoder for the image (I think). If there's noting wrong with the image, then this usually indicates some sort of corruption with the input stream, or perhaps you are using the same stream simultaneously? I also found that actually Win2D's WIC factory initialization is not thread-safe - see https://github.com/microsoft/Win2D/blob/0ac546bca974b9b454b99d9d31935071966537ea/winrt/lib/images/WicAdapter.h. It's difficult to see how this could cause the error you are seeing, but I could submit a PR to fix this (basically it would be better just to initialize the factory in the constructor). |
@benstevens48 Thanks! I am using the stream overload:
The images are correct, since using them in a single threaded fashion works. The input stream is always correct, since everything happens in memory -- I preload what I need in memory, and then convert each image to a stream. Not sure if the initialization is the issue, since the call above is not the first call to LoadAsync (thus, the WIC factory should already be initialized).
That makes sense regardless of whether it fixes my issue or not. Thanks! |
I've submitted a PR - #807 - to ensure thread safety. Maybe you can check if it fixes the problem (you will have to build a local copy of Win2D) but I doubt this was the problem though. I couldn't reproduce the issue using the unfixed version so I can't really say for sure. With regards to it not being the first call to LoadAsync - actually, one thing I didn't realize until recently is that you shouldn't store a reference to a COM object in a global/static variable in a C++ app, because it will be destructed after COM has shut down and cause an access violation. See https://devblogs.microsoft.com/oldnewthing/20210208-00/?p=104812. Therefore in fact Win2D uses the method of only keeping a weak reference in the static variable, so if there are no in-use copies of the WIC factory (or the wrapping singleton instance) then it will actually be destroyed and then re-created again later if needed. (Why does everything have to be so complicated!!) |
@benstevens48 Many thanks! My apologies for the late reply! |
@benstevens48 I finally figured this out. Sorry for the late reply, I've had a few shots at this in the last few months, but never got to the root of the issue. Finally, I really got pissed a few days ago, and said I'll investigate, and debug within win2d. After quite a few hours of testing and googling this STUPID error, I figured it out: it was a bug in my code, namely I was using a file stream from several threads - and sometimes clearly some of the memory bytes were filled incorrectly. And Long story short, with my internal fix, it works 100% correctly. This was a really weird one! |
This will happen even if I'm using a different canvas devices on each thread.
Why is this, and is there a workaround?
Can this be fixed?
The text was updated successfully, but these errors were encountered: