J'ai une classe statique qui crée plusieurs threads de travail dans son constructeur. Si une exception se produit avant que les travailleurs aient été créés, mon gestionnaire Application.ThreadException (utilisé pour fermer l'application si une erreur ne peut pas être récupérée) se déclenche normalement et tout va bien. Une fois que le premier thread de travail a été créé, en plus du déclenchement du handler, je reçois un message "MYAPP a rencontré un problème et doit être fermé." Nous sommes désolés de ce désagrément. " boîte de dialogue pour le rapport d'erreurs MS.Gestion des exceptions de constructeur statiques dans une application multithread
Dans cette instance spécifique, je peux réorganiser le code pour créer les derniers threads (après tout problème d'initialisation/d'accès aux ressources qui aurait pu déclencher une exception) mais ce n'est rien de plus qu'un problème et ne me donne pas toute information sur ce qui se passe réellement.
J'espère avoir excisé suffisamment de code de mon application pour montrer ce que j'essaie de faire ici.
class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
try
{
Application.Run(theForm);
theForm.Dispose();
}
catch (Exception e)
{
//doing this to use the same handler here and for Application.ThreadException
ThreadExceptionEventArgs argsEx = new ThreadExceptionEventArgs(e);
FatalExceptionHandler(null, argsEx);
}
finally
{
MyStaticClass.KillThreads();
}
}
public static void FatalExceptionHandler(object sender, System.Threading.ThreadExceptionEventArgs ex)
{
Exception e = ex.Exception;
try
{
//lots of stuff to give more useful error messages for known problems
//and display them in a messagebox.
}
// if anything went wrong scraping the exception text for formatting, show the raw value.
catch
{
MessageBox.Show(e.Message);
return;
}
// after showing the MessageBox, close out the app.
finally
{
System.Environment.Exit(1);
}
}
}
class MyStaticClass
{
static MyStaticClass()
{
myThread = new Thread(new ThreadStart(SomeMethod));
//if this exception is thrown everything works normally
//Throw new Exception("KABOOM");
myThread.Start();
//if this exception is thrown a windows error reporting dialog appears
//along with the messagebox from program.FatalExcetion handlder
//Throw new Exception("KABOOM");
}
public void KillThreads()
{
//clean up the worker threads
}
}
Je pensais que le constructeur était toujours appelé, au plus tard, quand un membre/méthode/propriété de celui-ci a été accédé. –
C'est correct, mais un "si et quand" le membre est accédé, et il n'aborde toujours pas a) le thread sur lequel le constructeur s'exécute et b) quand il s'exécute par rapport à la durée de vie de l'application. Voici une règle empirique que je viens de créer et qui pourrait vous aider: si le code dans le constructeur statique ne pouvait pas être exécuté deux fois de suite sans modifier le comportement du programme, déplacez le code vers une méthode d'initialisation statique. –
Si je déplace tout le code du constructeur statique vers une méthode initialize, y a-t-il une raison de garder le constructeur autour? –