-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Metadata/TypeDef view increadibly slow #2151
Comments
Thanks for reporting this! Would you be able to share the assembly that causes the problem? I just tried this with .NET Core 3.1 System.Private.CoreLib.dll (TypeDef has > 2000 rows in this case) and I cannot reproduce the problem. Thank you! |
I tested with Core 3.1.7 System.Private.CoreLib.dll, and it still reproduces. Took approx 17 seconds from clicking an empty area in the scroll bar, to move one screenful, until the data was actually presented. CPU consumption was virtually nonexistant during the time. I then tested swiching to the Field list (7377 entries). This was faster. Only took 6-7 seconds. Debug build of ILSpy (4b716e2 to be precise), built for 4.7.2, running on (I presume) Microsoft's 4.8 JIT+runtime. I find it utterly baffling that it only happens in this kind of views, and with no measurable CPU consumption. I wonder what in the hell Microsoft is doing here, and with that call-stack from hell it sure won't be an easy task trying to find the bug (I'm currently leaning towards calling it "their bug", but while tempting I'll hold off on that until proof is available :-) ). EDIT: When first entering the TypeDef view by clicking its node in the tree control, it only took 1-2 seconds, and this time it consumed CPU (I'd guess that's mainly the lookup ILSpy is doing). EDIT2: While on a hunch looking at it using ProcMon, while it didn't display any problems with waiting for I/O, I did notice it closing+reopening the display font on every scroll operation. While that is seemingly not taking a lot of CPU time, it's definitely not what I'd expect, so that part might at least be something to look into (probably belongs in a separate issue). EDIT3: OK, I think the fog is lifting, even if only a little bit. Running ILSpy under the VS profiler, using the "Timeline" profiling method, it displays an insane five thousand "Layout" operations, for scrolling a single screenful of data, and the call stack from that one is deep enough for your brain to shut down to protect you/itself from trauma. The problem (what I'd call bug, but Microsoft true to their usual apathy and customer-disdain would probably call "by design") seems to emanate from PART_RowPresenter inside System.Windows.Controls.Primitives.DataGridRowsPresenter. That's the last entry in the hierarchy of idle-time-burners I can find, where a mere 50 calls to it consumed almost no CPU but 14.81 seconds wall-clock time! I'm going to dig deeper into this cesspool, but I first need to find a thick enough hazmat suit for protection so it might take a while. |
Thanks for following up! However, on my machine clicking the TypeDef node takes about 1 second, and scrolling one screen (39 rows) takes about the same amount of time. I am running this on a Lenovo ThinkPad E590, Intel Core i7 8565U, base speed 2.0GHz, 32 GB RAM, an SSD. One second for scrolling one screen is still slow, but it's what I have come accustomed to because, well, WPF DataGrid. Have you tried profiling? |
Hmmm... I don't see a single element that causes the long delays... what's further down in the tree? |
Nothing useful. Just specks of milliseconds. However, I have now tried to dig deeper into this, and I think I just enetered an episode of the Twilight Zone. Running ILSpy under the debugger with env. var. EDIT: EDIT2: This includes attaching a (the VS) debugger to it. Starting ILSpy from e.g. command-prompt it runs dg-slow for this scroll operation. Attach a VS debugger to the running instance, and it starts running faster (still slow, ~2 seconds per scroll without any CPU used, but way faster than the 14-17 seconds without the debugger attached). EDIT3: Not the debugger as-such. It's the "Enable UI Debuggin Tools fo XAML" debugger setting that makes it run faster, possibly because it introduces some delays that breaks the WPF-internal deadlock. Turning off that setting, it exhibits the same slowdown as if free-running. Do you know/understand what those "PART_*" thingies are? They are clearly not method names, and from my understanding what I must do now is to try to find that time-hogger and disassemble the hell out of it to retain some semblance of sanity, but I haven't got a clue of where to start. Follow-up to EDIT2: As it currently stands, this is more and more starting to look like a bug in Microsoft's code, that may be impossible to work around in ILSpy. Do you know what of the gazillion Microsoft repo's would be the correct one for something like this? Thanks for you interest and patience. :-) |
The "PART_" identifiers are used by WPF controls to make ControlTemplates work: Parts of the template that are required by the "code-behind" are marked as "PART_whatever". So it's just the Name property of the WPF control, which then can be used to access the part after the template/XAML is applied. The tree seems to show the type name of the control if no name was set. (Note: the "PART_" in front is just a convention, seems that WPF's DataGrid doesn't follow the convention itself, see, e.g., "DG_ScrollViewer"). If you want to dig down in the WPF Visual Tree, you can use Snoop. https://github.com/snoopwpf/snoopwpf |
I'm sure I don't want to do that. :-) But thanks for the link, it might come in handy. Well, I have come to a brick wall. I'm leaving this issue open until I have referenced it in an issue in some Microsoft-managed repository. With Microsoft keeping this crap closed source (whether out of spite or to protect the world from their LSD-induced madness could be up for discussion), it's practically impossible for me to debug it deeper than finding "something in a callstack-from-hell is trying to get a lock on a text, while presumably some other (non-running) thread is holding a lock on it". As such, I'll just have to find a Microsoft repo. to report this to, in an attemp to get it resolved (only to get the issue closed as "WONTFIX", "BYDESIGN", or the wonderfully helpful and customer-oriented "Wrong repository" (basically, "piss off, we don't care") - yeah, my confidence in Microsoft is at a well-founded all-time low, so bad I don't even bother trying to be polite about it anymore).EDIT: Well great... There is no github repo fro WPF Framework, and I sure won't jump through all the hoops and enable running scripts from umpteen untrusted websites just to file a bugreport to them... Bah. I'll just use dnSpy for metadata lookup from now on. Sorry for the noise. |
Probably not a bug that can be fixed by ILSpy. Seems to be a bug deep down in Microsofts proprietary code. |
That is very unfortunate...
Have you tried https://github.com/dotnet/wpf ? ... unfortunately it will take some time (sorry!) until we'll be able to move ILSpy to "WPF Core", which is open source and hosted in that repository... |
Unfortunately that repo only touches ".NET Core". For Framework they refer you to some other websites that forces you to run javascripts from umpteen different sites. I accepted that while it was possible to use the VS "integrated" feedback tool (so it only polluted the "system integrated" web browser that I never intentionally used), but since the VS team killed that tool off without a single word of warning, I sure am not gonna pollute my main browser with that crap if I can avoid it. I also remember some WPF "Core" team article (or blog entry, or whatever) where they stated (in no uncertain terms) that it will be only partially open source, meaning it will only run on Windows. Anyway, just to have the final piece of my findings documented somewhere (might as well hang in limbo here, than in some Microsoft repo where they ignore it forever too, eh), here's... Where it hangs without any CPU consumptionAt least that seems to be the place, since it always ends up there when attaching debugger and breaking into the running/hanging ILSpy during the long hang intervals. I get a headache and get sick to my stomach just looking at that call stack, needing to fight back the urge to vomit.
Cheers. |
From some googling I think Do you have some other software (e.g. input method editors) running that might be using text services framework? Maybe the problem is that ILSpy uses too many text boxes, thus overloading the TSF communication. |
Thanks Daniel, good sleuthing. I have no IME's or text input- output- "services" of any kind intentionally running on this desktop computer. In fact, all wasteful Microsoft malware I can disable without Microsoft totally breaking Windows itself, is stopped, and disabled. I did however make the mistake of letting Microsoft "upgrade" the OS installation to (the idiotically named) "2004" in a vain hope they would have fixed some vulgarly obvious bugs (not too surprisingly, they hadn't), so it's entirely possible they included this breakage in this version as an "easter egg". However, Microsoft have "fixed" CtfMon (or so they claimed) two years after I first reported its horrendous memory leaks, and according to them it was indeed related to text boxes (whether USER32 EDIT's or WPF's equivalent is unknown). It wouldn't surprise me the least if they broke something else in that process.
That is certainly plausible, since that's not the way to do it. Imagine how something like Excel would work (or rather, not work) if every cell was an EDIT box. :-) a An EDIT should only be instantiated on top of an editable cell once a user actually invokes an edit operation. During all other time it should only be rendered text. In this case I don't even think ILSpy allows editing anything in those tables? I'll give that suggestion a shot and report back. Thanks for the input. |
Oh yeah. HELL yeah! @dgrunwald You came as a guardian angel and hit the nail on the head. Not only is it now a few thousand times faster (with the bug I experience, but likely also a bit faster in general), it's consuming less memory. As I don't know diddle-squat about the XML-wrapped XAML-this and WPF-that, please see this only as an example. It seems to work for me, for this scenario, but I can take no responsibility for it working for all uses. For your consideration:
|
I have refactored the Metadata DataGridCell template... Please note that copying values from cells is now available through a context menu entry. Thank you for your understanding! |
Thanks Siegfried. I'd still like to really understand where Microsoft introduced this, since it was 100% reproducible for me, but you didn't experience it at all. I hit the problem on Windows 10 x64 10.0.19041.450 (a.k.a. "2004"), with |
With the debugger attached, it did lag for me only a little bit. However, without the debugger attached it was very noticeable. |
Aha. I got the impression you didn't see the problem at all. Now all is clear. Thanks. |
Steps to reproduce
ILSpy becomes unresponsive for extended periods of time, upwards of 20-30 seconds experienced. The strange thing is, NO noticable CPU or disk activity or is taking place during this waiting time - it just "hangs".
Bouncing back and forth between two pagefuls of data is faster, maybe as "low" as "only" a second, but still orders of magnitude slower than what would be expected, and again without any CPU load matching this slowness.
Trying to find the culprit, debugging displays one single WAP/WEP/WPF/WPA (whatever they are called) event, a single GC a few hundred ms after the view has scrolled. So no help there.
While in the debugger, there are a bunch of threads belonging
Microsoft.VisualStudio.DesignTools.WpfTap.dll
, but I suspect those are only Miscrosofts usual way of polluting debugging attempts with tons and tons of junk, since it seems to resolve toc:\program files (x86)\microsoft visual studio...\common7\ide\commonextensions\microsoft\xamldiagnostics\Framework\x64\Microsoft.VisualStudio.DesignTools.WpfTap.dll
(try typing that path manually :-) )
Breaking into the debugger while in this hung state (you might have to be quick, so ILSpy doesn't finish its processing while you try to break into it from the now topmost VS) displays something that could make a grown man cry, of shame, seeing the way Microsoft is making the craft of software development look like it's worth less than shoveling manure.
**call stack from hell**:
So maybe the problem isn't ILSpy at all, but Microsofts excellent software designers and programmers attempting to provide the Genuine Windows Experience by adding implicit "Please Wait...(tm)" functionality, while leaving it up to the users of their code to display that message? :-)
If that's the case, I guess there's nothing one can do about it in this context, but it might be worth being aware of (implementing that hated "Please Wait...(tm)" dialog with an animated progress bar might be taking it a bit far, as it could be seen as validation of Microsofts ways).
The text was updated successfully, but these errors were encountered: