|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
gc.KeepAlive - is this the reality of garbage collectionI have a problem with garbage collection. An msdn example says generally the following: I have a class TestCls. With a Property MyProp. Then normally I would write: void MyFunc() { TestCls tc = new TestCls(); int u = tc.MyProp; .... no further use of tc .... } The example says this would not work, because the gc could work (finalizer called) before tc.MyProp has finished. This is a catastroph. The example says I had to write: void MyFunc() { TestCls tc = new TestCls(); int u = tc.MyProp; .... no further use of tc .... gc.KeepAlive(tc); } Think about this, if you have many such objeckts and calls in a method. Furthermore: I have tested the example of the msdn: gc Class/ GcMethodes/KeepAlive Methode which is at ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.en/cpref2/html/M_System_GC_KeepAlive_1_b4c5a2da.htm in Msdn VS 2005. I mean the FIRST example. I have a computer with 2 cpus (intel dualcore), but the example does not works as described. So question is it reality? Have I to use in this case (only manged code, no interop) the KeepAlive-Method? (I only mean this sample with pure dotnet, if I use interop the use of KeepAlive is clear for me). Thank you for any help. Rolf Welskes Rolf Welskes <rolf@nospam.nospam> wrote:
Show quote > I have a problem with garbage collection. Well, it depends what you mean by "work".> > An msdn example says generally the following: > > I have a class TestCls. > With a Property MyProp. > > Then normally I would write: > > void MyFunc() > { > TestCls tc = new TestCls(); > int u = tc.MyProp; > > .... no further use of tc .... > } > > The example says this would not work, because the gc could work (finalizer > called) before tc.MyProp has finished. > This is a catastroph. It entirely depends on the situation. There are very few situations in which it's actually a problem. <snip> > So question is it reality? Yes, but a reality which very rarely affects people.It's usually only an issue if you have a finalizer which may do something like closing a handle, and that handle is used in a method which may still be executing when the finalizer executes. I can't remember the last time I wrote a finalizer... -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too On Sat, 24 Mar 2007 05:00:12 -0700, Rolf Welskes <rolf@nospam.nospam> =
wrote: > [...] I admit that Jon's answer is the safest. I suppose there's some bizarre=> void MyFunc() > { > TestCls tc =3D new TestCls(); > int u =3D tc.MyProp; > > .... no further use of tc .... > } > > The example says this would not work, because the gc could work = > (finalizer called) before tc.MyProp has finished. > This is a catastroph. = scenario in which the code you posted might do something you didn't expe= ct. However, just because the class instance referenced by "tc" isn't = referenced after that line, that doesn't mean that the GC could clean it= = up before the assignment to "u" is done. If the "get" for the property = = actually needs something in the instanced referenced by "tc", then the = "get" itself has references to the instance which would prevent = collection. If the "get" doesn't actually need something in the instanc= e, = then it's fine for the instance to be collected before the "get" returns= , = because it's not actually using it. Either way, the code works fine. I don't see any "catastrophe" here. Frankly, any time you think the = language introduces a "catastrophe", you should question your own = understanding of the language. After all, if the language really did ha= ve = such catastrophes in it, it's highly unlikely that it would be in such = wide use. Pete Peter Duniho <NpOeStPe***@nnowslpianmk.com> wrote:
> > The example says this would not work, because the gc could work There's slightly more to it than that. The getter could use some field > > (finalizer called) before tc.MyProp has finished. > > This is a catastroph. > > I admit that Jon's answer is the safest. I suppose there's some bizarre > scenario in which the code you posted might do something you didn't expect. > > However, just because the class instance referenced by "tc" isn't > referenced after that line, that doesn't mean that the GC could clean it > up before the assignment to "u" is done. If the "get" for the property > actually needs something in the instanced referenced by "tc", then the > "get" itself has references to the instance which would prevent > collection. within the instance to start with, and then do a bunch of other things. After it's last used the instance, the instance can be garbage collected. The reason this becomes a problem is when you have something like: IntPtr handleInstanceVariable; void DoSomething() { // Last reference to anything in the instance IntPtr handle = handleInstanceVariable; // Call to a static method DoSomethingWithHandle(handle); } ~WhateverType() { Close(handle); } Clearly DoSomething() doesn't want the handle to be closed during the call to DoSomethingWithHandle, but the garbage collector doesn't know that... so you'd need to put a call to GC.KeepAlive at the end of DoSomething(). I suspect that the optimisations that can be made with the memory model make this situation even worse, but I don't know for sure - it depends at what point the CLR determines (for each method) that the method no longer uses anything from the instance. There's a blog entry about all of this written by Chris Brumme, which is where I first learned about it. Worth a read: http://blogs.msdn.com/cbrumme/archive/2003/04/19/51365.aspx -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too On Sat, 24 Mar 2007 12:17:08 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote: > [...] I think you mean "Close(handleInstanceVariable)", right?> ~WhateverType() > { > Close(handle); > } I agree that the scenario you describe is an issue. I just don't think it qualifies as a catastrophic defect in .NET. :) As near as I can tell, the problematic scenarios are generally similar to the one you describe, where some unmanaged resource is involved. As long as the reference is to a managed resource, the GC can track it. And the problem exists not in the caller to the "get" method, but rather the class using the unmanaged resource itself. So while a bug could show up in the example the OP posted, the problem wouldn't be with the code he posted, but rather due to a buggy class used by that code. I don't mean to minimize the importance of understanding these issues. Obviously they are important, are not always intuitive, and need to be taken into consideration when dealing with the relevant situations. But as a general rule, they don't come up very often, and don't reflect any sort of serious defect in .NET. IMHO, to fix .NET so that the issues didn't exist (e.g. use a more conservative algorithm for determining object lifetime, or somehow track references to unmanaged objects) would hurt .NET more than it helps. Pete Peter Duniho <NpOeStPe***@nnowslpianmk.com> wrote:
> On Sat, 24 Mar 2007 12:17:08 -0700, Jon Skeet [C# MVP] <sk***@pobox.com> Yes. Doh. (That's what I get for not writing a sample that compiles :)> wrote: > > > [...] > > ~WhateverType() > > { > > Close(handle); > > } > > I think you mean "Close(handleInstanceVariable)", right? > I agree that the scenario you describe is an issue. I just don't think it Oh absolutely. It's the kind of thing one wouldn't expect without > qualifies as a catastrophic defect in .NET. :) knowing about it though. Before I read about it, I'd always assumed that an object wouldn't be collected while a method was running "on" that object. Reality was a surprise :) > As near as I can tell, the problematic scenarios are generally similar to Exactly. The fix (calling GC.KeepAlive) is within the class itself, not > the one you describe, where some unmanaged resource is involved. As long > as the reference is to a managed resource, the GC can track it. And the > problem exists not in the caller to the "get" method, but rather the class > using the unmanaged resource itself. So while a bug could show up in the > example the OP posted, the problem wouldn't be with the code he posted, > but rather due to a buggy class used by that code. within the caller. > I don't mean to minimize the importance of understanding these issues. I'm not sure about the last bit - granted I'm far from an expert on GC, > Obviously they are important, are not always intuitive, and need to be > taken into consideration when dealing with the relevant situations. But > as a general rule, they don't come up very often, and don't reflect any > sort of serious defect in .NET. IMHO, to fix .NET so that the issues > didn't exist (e.g. use a more conservative algorithm for determining > object lifetime, or somehow track references to unmanaged objects) would > hurt .NET more than it helps. but I doubt that there are that many situations where it's actually positively desirable to collect an object while a method is running "on" it. Why can't "this" just automatically be a root as far as the GC is concerned? Maybe there are some significant use cases I haven't considered. -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too Jon Skeet [C# MVP] <sk***@pobox.com> wrote:
> I'm not sure about the last bit - granted I'm far from an expert on GC, I've thought of one possible problem - inlining of instance methods > but I doubt that there are that many situations where it's actually > positively desirable to collect an object while a method is running > "on" it. Why can't "this" just automatically be a root as far as the GC > is concerned? Maybe there are some significant use cases I haven't > considered. which just call static ones. The GC might not know it's even in the instance method... -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too Jon Skeet wrote:
Show quote > Peter Duniho <NpOeStPe***@nnowslpianmk.com> wrote: 'this' isn't a root in the cases where the GC collects the instance even> > On Sat, 24 Mar 2007 12:17:08 -0700, Jon Skeet [C# MVP] <sk***@pobox.com> > > wrote: > > > [...] > > As long > > as the reference is to a managed resource, the GC can track it. > [...] > > IMHO, to fix .NET so that the issues > > didn't exist (e.g. use a more conservative algorithm for determining > > object lifetime, or somehow track references to unmanaged objects) would > > hurt .NET more than it helps. > > I'm not sure about the last bit - granted I'm far from an expert on GC, > but I doubt that there are that many situations where it's actually > positively desirable to collect an object while a method is running > "on" it. Why can't "this" just automatically be a root as far as the GC > is concerned? Maybe there are some significant use cases I haven't > considered. while executing code from its methods, because the 'this' instance is no longer reachable from any roots, including registers, stack, static fields etc. To fix the problem, the JIT codegen would have to make sure it never deregisters the 'this' value even if it is not used for the remainder of a method, or alternatively push it onto the stack, so the GC can find it. When I think about it, it could be a reasonable candidate for a fix - the performance impact would have to be measured of course, but I suspect it wouldn't be large. I believe the precaution is only necessary for instance methods defined on types which have a finalizer, but of course a not-loaded-yet descendant might add a finalizer... -- Barry Barry Kelly <barry.j.ke***@gmail.com> wrote:
> > I'm not sure about the last bit - granted I'm far from an expert on GC, Exactly - that's my point. This situation would be easier if it *were* > > but I doubt that there are that many situations where it's actually > > positively desirable to collect an object while a method is running > > "on" it. Why can't "this" just automatically be a root as far as the GC > > is concerned? Maybe there are some significant use cases I haven't > > considered. > > 'this' isn't a root in the cases where the GC collects the instance even > while executing code from its methods, because the 'this' instance is no > longer reachable from any roots, including registers, stack, static > fields etc. a root. > To fix the problem, the JIT codegen would have to make sure it never I suspect inlining would be a problem. If I call foo.SomeMethod() which > deregisters the 'this' value even if it is not used for the remainder of > a method, or alternatively push it onto the stack, so the GC can find > it. When I think about it, it could be a reasonable candidate for a fix > - the performance impact would have to be measured of course, but I > suspect it wouldn't be large. just calls a static method, passing in a field value from foo, then that could easily be inlined currently - but not if the GC needs to know that foo.SomeMethod() is really executing. > I believe the precaution is only necessary for instance methods defined True. Just another reason to make classes sealed unless you've > on types which have a finalizer, but of course a not-loaded-yet > descendant might add a finalizer... specifically designed them to be derived from :) (I must go round my miscutil classes and make them sealed where appropriate some time...) -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too Jon Skeet wrote:
> Barry Kelly <barry.j.ke***@gmail.com> wrote: I don't agree. The compiler needs to do lifetime analysis of variables> > To fix the problem, the JIT codegen would have to make sure it never > > deregisters the 'this' value even if it is not used for the remainder of > > a method, or alternatively push it onto the stack, so the GC can find > > it. When I think about it, it could be a reasonable candidate for a fix > > - the performance impact would have to be measured of course, but I > > suspect it wouldn't be large. > > I suspect inlining would be a problem. to determine a register allocation strategy. To prevent deregistering, or to cause it to spill out to the stack, all that is required is creating a phantom use at the end of all basic blocks that exit the function. Inlining should handle this use appropriately, otherwise they'd have a bug if the use was genuine and was evaluated in an expression. An expensive (presuming the JIT compiler doesn't have clever knowledge about it) way of doing this would be to inject an implicit call to GC.KeepAlive(this) after evaluating the expression in a 'return' statement, but before the IL ret code is emitted; and that includes implicit return by dropping off the end of the function, and void returns where there isn't an expression. An IL opcode would probably be better. And there would still be problems with tail. call, but if you're dealing with tail. call, you ought to intuitively know that your frame is no longer on the call stack etc. BTW, I write compilers for a living :) -- Barry Barry Kelly <barry.j.ke***@gmail.com> wrote:
> > I suspect inlining would be a problem. That's true.> > I don't agree. The compiler needs to do lifetime analysis of variables > to determine a register allocation strategy. To prevent deregistering, > or to cause it to spill out to the stack, all that is required is > creating a phantom use at the end of all basic blocks that exit the > function. Inlining should handle this use appropriately, otherwise > they'd have a bug if the use was genuine and was evaluated in an > expression. > An expensive (presuming the JIT compiler doesn't have clever knowledge I'm not sure whether an IL opcode would be necessary - just a change to > about it) way of doing this would be to inject an implicit call to > GC.KeepAlive(this) after evaluating the expression in a 'return' > statement, but before the IL ret code is emitted; and that includes > implicit return by dropping off the end of the function, and void > returns where there isn't an expression. > > An IL opcode would probably be better. And there would still be problems > with tail. call, but if you're dealing with tail. call, you ought to > intuitively know that your frame is no longer on the call stack etc. what the JIT works with the GC. Unless, of course, you wanted different languages to have different semantics. > BTW, I write compilers for a living :) Ah :)-- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too Hi Rolf ,
Besides other community member's replies, below is my comment: You only need to use GC.KeepAlive() method while dealing with unmanaged resource/code. If you are using pure managed code without unmanaged interop, there is no need to keep the managed object alive. Actually, if you do not deal with unmanaged resource, there is no need to implement IDispose interface or Finalizer. While dealing with unmanged resource/code, you only need to use GC.KeepAlive if the unmanaged code is executed asynchronously with your managed code(such as in background thread). This is because the reference to you managed object is alive during the entire scope in that method(unless you set the object reference to null explicitly). If the unmanaged code finished using the unmanaged resource synchronously in the method, there is no need to keep the object alive. Actually, this is a rare situation. Anyway, if you still have anything unclear, please feel free to tell me, thanks. Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Jeffrey Tan[MSFT] <je***@online.microsoft.com> wrote:
> Besides other community member's replies, below is my comment: I'd put it as only needing it while implementing a finalizer.> > You only need to use GC.KeepAlive() method while dealing with unmanaged > resource/code. > If you are using pure managed code without unmanaged Well, hang on. There are other reasons for implementing IDisposable > interop, there is no need to keep the managed object alive. Actually, if > you do not deal with unmanaged resource, there is no need to implement > IDispose interface or Finalizer. than merely collecting unmanaged resources, and while I wouldn't implement a finalizer without *directly* having access to unmanaged resources, it's still good practice to implement IDisposable if you have a reference to something else which implements IDisposable (eg a stream). In that case you don't directly have access to the unmanaged resource, but you still want to be able to ask the managed type to clean up the unmanaged resource in a timely manner. > While dealing with unmanged resource/code, you only need to use Well, the finalizer thread is always a separate thread anyway, so that > GC.KeepAlive if the unmanaged code is executed asynchronously with your > managed code(such as in background thread). doesn't really cut the scenarios down. -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too Hi Jon ,
#1, Yes, your comment is right. Actually, this scenario means indirectly using the unmanaged resource. #2, Oh, yes, I have performed a reading to cbrumme's WebLog entry below. It is really informative to reference lifetime and GC.KeepAlive. It seems that I originally have some misunderstanding on the reference lifetime. I would second a highly recommendation to Rolf this blog entry: "Lifetime, GC.KeepAlive, handle recycling " http://blogs.msdn.com/cbrumme/archive/2003/04/19/51365.aspx Jon: thank you very much for the sharing! Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Hello,
ok, what you say would be fine. BUT: Look in the sample in the msdn for KeepAlive. Here you find sample one: This is pure managed code with one thread, the second thread is only for visualize the results. And in this sample you have: .... MyCls a = new MyCls() a.fu() GC.KeepAlive(a); //this sample is what make the trouble !!! Thank you for any help. Rolf Welskes Hi Rolf ,
Thanks for your feedback. I can not find "MyCls" class in the KeepAlive MSDN link, I assume you mean the following sample in MSDN, yes? Example ex = new Example(); byte[] res = ex.Hash; ... GC.KeepAlive(ex); Yes, this sample is not confined to the unmanaged code scenario; it is used to address one subtle JIT issue with GC. The Microsoft Achitect Chris Brumme has discussed this subtle issue in his WebLog below: "Lifetime, GC.KeepAlive, handle recycling " http://blogs.msdn.com/cbrumme/archive/2003/04/19/51365.aspx You may give it a detailed reading. Hope this is clear. Thanks. Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Hello,
thank you for your information. I have read the article you mentioned. But the problem is to important. Think we have ClsA with a finalizer and unmanaged resources. ClsA.Fu() may be a funktion in this class. A. I would agree with: void Fu() { ......... do something with unmanged resources GC.KeepAlive(this); } In a client witch uses this class I need NOT to use KeepAlive. I simple could write: ClsA a = new ClsA(); a.Fu(); //Thats all no KeepAlive. B. Bad would be: if I am in client code which uses ClsA and had: ...... ClsA a = new ClsA(); a.F(); GC.KeepAlive(a); Bad because I would not know when witch class of a not own library has such situations. So the questions is: If I use a library, and I do not use any unmanged resources and no finalizers in my code, can I be sure that I need not to use KeepAlive? Clearly, this question means, is all in the library as described in point A. (not point B.). Clearly, you can only say this for the dot net library (other libraries of any vendors, so are a risk). Thank you for help. Best Regards Rolf Welskes Hi Rolf ,
Thanks for your feedback! Yes, I see your concern. In situation B, it is the responsibility of the class library author to take care of the finalizer thread/application thread race condition issue. So if you are the client, I do not think you should be borther to call GC.KeepAlive(a); If your library classes do not consume any unmanaged resource, there is no such problem of using GC.KeepAlive(a). This is because all the managed objects can always be monitored by the GC reachability feature. It is impossible that one thread is still using a managed object while GC thread is trying to destroy it. This is the situation we are sure to be safe. If you still have anything unclear, please feel free to tell me, thanks. Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Hello,
thank you for your help. I think I can live with this, but I wish any time it would be better. Thank you again and best regards Rolf Welskes ""Jeffrey Tan[MSFT]"" <je***@online.microsoft.com> schrieb im Newsbeitrag Show quote news:IFYQdEOfHHA.5016@TK2MSFTNGHUB02.phx.gbl... > Hi Rolf , > > Thanks for your feedback! > > Yes, I see your concern. In situation B, it is the responsibility of the > class library author to take care of the finalizer thread/application > thread race condition issue. So if you are the client, I do not think you > should be borther to call GC.KeepAlive(a); > > If your library classes do not consume any unmanaged resource, there is no > such problem of using GC.KeepAlive(a). This is because all the managed > objects can always be monitored by the GC reachability feature. It is > impossible that one thread is still using a managed object while GC thread > is trying to destroy it. This is the situation we are sure to be safe. > > If you still have anything unclear, please feel free to tell me, thanks. > > Best regards, > Jeffrey Tan > Microsoft Online Community Support > ================================================== > Get notification to my posts through email? Please refer to > http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif > ications. > > Note: The MSDN Managed Newsgroup support offering is for non-urgent issues > where an initial response from the community or a Microsoft Support > Engineer within 1 business day is acceptable. Please note that each follow > up response may take approximately 2 business days as the support > professional working with you may need further investigation to reach the > most efficient resolution. The offering is not appropriate for situations > that require urgent, real-time or phone-based interactions or complex > project analysis and dump analysis issues. Issues of this nature are best > handled working with a dedicated Microsoft Support Engineer by contacting > Microsoft Customer Support Services (CSS) at > http://msdn.microsoft.com/subscriptions/support/default.aspx. > ================================================== > This posting is provided "AS IS" with no warranties, and confers no > rights. > > Hi Rolf,
Yes, I see your concern with this issue. However, this type of design is determined by CLR dev team, which goes out of my scope. Anyway, if you have strong concern over it, please feel free to let me known, I will help you to notify the CLR team, I think they are happy to hear from real concern customer to improve CLR. Thanks. Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. |
|||||||||||||||||||||||