2

I started asking this question here, and got very informative answers, but still can't get round the problem. That question has been closed as it's a known issue. I know it's a known issue: my question is what can I possibly do about it?

To summarise:

  1. VS debugger swallows unhandled exceptions occurring in a Form_Load event (or any calls therefrom) when debugging on Windows 64-bit systems (in my case, Win 7 64-bit). As it stands, this makes VS useless as a dev environment
  2. One suggestion was to move code into the constructor rather than the FOrm_Load event. I don't want to do that as it moves code out of sight into "designer-created" modules; those modules are full of code I'm not competent to change yet; and I don't trust the Designers not to wipe out or change code I put there.
  3. Another suggestion was to point unhandled exceptions to dummy empty exception handlers by inserting some code into an initial procedure (e.g. Sub Main). This works. The problem here is that Sub Main can only execute on startup if I switch off the Application Framework. Then I can't run the application with a lifetime of "until the main form or last form closes".
  4. I thought I'd got a Sub Main in a startup form running, and running at the right time (i.e. before Form_Load). Thus I can still use the Application Framework, and have this special code run before anything else. I may be wrong here. In any case, I've changed the code of that form a bit, and Main no longer runs in time - if it ever did (Form_Load runs first, and we have the same problem). Tried moving the code into Form_Load - but it itself causes an error.
  5. There's a supposed hotfix (KB976038). I applied that (restart needed): but now instead of the exception being swallowed, I get a vshost.exe application error, and still can't debug my code. Frustatingly, once I OK the application error, I get a glimpse of the VS debugger showing the usual Unhandled Exception box - but it disappears in about 1/10th of a second.

So what are my options?

The common thread here is that though I'm an experienced programmer, used to getting things done in VB.NET and VB6, and competent to understand the thorough explanations of what's causing this problem;

all the possible measures are really beyond my competence, and introduce too many gotchas that I may not even be aware of. I can't help thinking - why can I not just get down to coding, and deal with the inevitable coding mistakes I'll make, using a debugger that I can trust to break on an exception?

At the moment, I feel that if (with advice from those more expert than me) I somehow get VS to properly catch unhandled exceptions and break on them, this will only be for today. Who knows whether something I do in my code tomorrow, or next week, might not break the carefully-constructed safety-net that is making VS behave itself properly for the moment?

I freely admit that I shouldn't be allowed near the constructor/Designer-created code at this stage in my .NET expertise. I just want to get stuff done! So my options look like:

  • Learn all the hardcore stuff so that I never break the solution to this problem. This will take months if not years; or
  • Give up and go back to VS2008 Express on XP; or
  • Persuade the company to bin Windows 7 64 and gives us Windows 7 32 as a development OS.

Any ideas or suggestions welcome!

EDIT: As suggested by @roadwarrior below, here's the suggested workarounds in the answer to the original question, and what I've found with them:

1 Project + Properties, Build tab, change Platform target to AnyCPU

Already is set that way, and I can't change it. Tried changing TargetCPU away from "AnyCPU" to x86 or 64-bit - no effect.

2 Debug + Exceptions, tick the Thrown box for CLR exceptions

Makes running/testing a nightmare as soon as I start deliberately handling exceptions (which I do a lot). Every exception will result in a "stop", whether handled or not.

3 Write try/catch in the Load event handler

This is not going to be much fun either. At this stage of development, I want to see the line that's causing the problem. Always loathed debugging code back in VB6 that was in the scope of an On Error Goto someone had put into a procedure 6 steps up the call stack; I don't want to start out that way in my own projects!

4 Use Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException) in the Main() method so that the exception trap in the message loop isn't disabled in debug mode. This setting however makes all unhandled exceptions hard to debug, the ThreadException event is pretty useless.

I don't understand the comment in the final sentence. But something like this worked. What I did, as suggested by Neolisk in answer to my previous question, was this, in a Sub Main:

Public Sub Main()
    AddHandler Application.ThreadException, AddressOf ThreadExceptionHandler
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException)
    AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf UnhandledExceptionHandler

    Form1.Show()
End Sub

Friend Sub ThreadExceptionHandler(sender As Object, e As System.Threading.ThreadExceptionEventArgs)

End Sub

Friend Sub UnhandledExceptionhandler(sender As Object, E As System.UnhandledExceptionEventArgs)
End Sub

This was my version of neolisk's code - had to change it as in my version of VS/.NET (2012, 4.5) the two handlers needed to have different signatures. Two problems with this:

a) I can't get a Sub Main to execute on startup without unticking "Enable application framework". Once I do that, Form1.Show shows the form, we get to the end of Sub Main, and the form immediately disappears again, as the application is closing. I've subverted the application Settings' window's "Shutdown mode" setting, and don't understand how to get it back again.

b) This code works but I have very little idea why, how, whether it covers all exceptions, how it relates to what I may decide to tick/untick in the Debug/Exceptions dialog, or what other gotcha side-effects it might have at debug-time or run-time.

5 Consider if your code really belongs in the Load event handler. It is very rare to need it, it is however popular with VB6 programmers where Load was a big deal. You only ever need Load when you are interested in the actual window size after user preferences and autoscaling is applied. Everything else belongs in the constructor.

Fair enough. As an ex-VB6 programmer I'm used to using Form_Load, but let's progress and learn new things and move the code into the form's New() constructor (Let's hope I never have some code that really has to be in the _Load event). Now at least an exception dialog is shown when execution hits the problem line: but it's on top of a new window "No source available (crlf) The call stack contains only external code". In this particular case, the mistake in the code is debuggable from what I see here (it's a stupid typo) - but debugging like this when things get more complicated is going to be a nightmare: no chance to see what the state of anything is.

General comments:

1. Ran this project on the one Win7 32-bit machine we have (not my machine), and had no problems whatsoever. That's my preferred solution - to simply stop using Win7 64-bit for development.

2. Comments along the lines of "you're lucky you've got a debugger at all" are amusing, but not helpful. This is VS2012, which is supposedly a development environment with a debugger that works, and which we're going to have to pay £££ for. I've programmed for long enough to know when I know what I'm doing, and when I'm messing around with stuff I shouldn't be because I don't understand it. What I specifically don't understand is not the underlying structures (I cut my teeth on ZX81 machine code, don't want to go back there...), but VS itself. I'm happy to learn more about e.g. changing exception handlers in VS, as I need to, but definitely don't want to dive right in there, ignorantly, as a basis for my development environment.

4

2 回答 2

2

您的问题已作为重复问题关闭,而不是因为这是一个已知问题。Hans Passant的原始问题有一个很好的答案,讨论了可能的解决方法。

请让我们知道各种变通办法中有哪些是“硬核”,我将尝试提供简单的解释。实际上,我认为进一步探索这对您有好处,因为它将提高您对引擎盖下发生的事情的理解。

于 2012-11-16T16:07:06.053 回答
1

关于您的担忧#3:尝试使用ShowDialog()而不是Show(),它使应用程序运行直到此(主)表单关闭。我们有一个像这样运行的生产应用程序。如果您没有主窗体,您可能需要重新考虑您的设计。

在离开 x64 之前,请考虑从 2008 R2 开始,没有 32 位版本的操作系统。这意味着如果您要在应用程序服务器上运行您的软件,那将是 x64,因此您必须适应它。

于 2012-11-16T19:45:11.013 回答