Hi Phill,
In fact, I'm using VSWebProjectItem.Load/Unload method for Web site
projects. This works fine. Moreover, I call
VSWebProjectItem.WaitUntilReady after Load. I don't know whether this is
necessary just to get FileCodeModel.
For web application projects this doesn't work because it is normal
project and projectItem.Object cannot be cast to
VsWebSite.VSWebProjectItem. As I wrote, you never get Null for
FileCodeModel in web application because VS automatically loads the
document in the background if needed. The problem is that this process
allocates 8 GDI objects for each document. And they don't seem to be
destroyed until all references to file code model (and its properties)
are released and GCed. So if you have web application with 1200 files
and you call e.g. ProjectItem.FilecodeModel.CodeElements.Count for each
of them in one loop, you reach 9999 GDI objects count limit in few
seconds and your VS becomes unstable.
In this case you cannot use VSWebProjectItem.Unload method nor you can
call Window.Close because there is no Window object. So you have three
options here:
1. Call ProjectItem.Open before accessing FileCodeModel and then call
Window.Close, as described in Carlos's article. This is fine if you get
FileCodeModel once, store all info you need locally and then you will
never need FileCodeModel again. This is not my case. I read some info
first, e.g method names. Then during the program execution there may be
a need to read method source code, so I need to read e.g. StartPoint
which automatically loads the document if already not. It's impossible
to call Open and Close every time I access document.
2. Even when you didn't open window for the ProjectItem manually, you
can open it for loaded document anytime and then immediately close it.
This will release also all GDI (and memory) resources that were
allocated for it before. This was my case. I just called Open and Close
method on places where FileCodeModel wasn't needed anymore. This worked
fine but very slow. It's because Open and Close was used on every
project item, even it was never used and loaded. I needed to do it for
every projectItem because there is no way to tell whether the document
was loaded in memory and used for e.g. getting the FileCodeModel or not.
3. So I found better solution, which is variation of 2. First, I
determine whether the document was loaded in the background and close it
if yes. This cannot be done just with automation, I needed to call VS
services. This was my first use of VS package objects but it seems to
work. If anyone is interested, I can post the code here.
So now it works for me but it is Open-Close game which loads and then
closes one document several times. One solution is to open it once,
cache all info locally and close it forever. The problem is that getting
all possible info (e.g. method parameters) is too slow. Even slower then
opening and closing document several times. My VSdocman only reads the
info (and then caches it) when it first needs it. Some info is never
needed which we don't know in advance.
I hoped there is a way to use web projects the same way as other
projects. In normal VB or C#, VS loads all documents in the memory.
There is no GDI leak. Memory is not a problem these days. My Vsdocman
can use all FileCodeModel objects any time. When it finishes, all
references to FileCodeModel objects are released.
Peter
pjollans wrote:
>
>
> Hi Peter,
>
> I haven't really looked at your problem in detail, but I saw the
> reference to Carlos's article
>
> http://www.mztools.com/Articles/2006/MZ2006017.aspx
> <http://www.mztools.com/Articles/2006/MZ2006017.aspx>
>
> and I wanted to send some feedback to Carlos on this article anyway.
>
> I find even Carlos's technique of opening and closing the file before
> fetching the FileCodeModel unreliable. I have found a new tip, which I
> am currently trying out, in the link:
>
>
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=\
112636
>
<http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID\
=112636>
>
> This involves adding a reference to VsWebSite.Interop.dll and using
> the VSWebProjectItem.Load method. I wasn't previously even aware of
> the VSWebSite component! Maybe this is of some help to you.
>
> Phil