9
votes

C #, Winforms: listbox.items.add génère une exception exceptionnelle.

Tout d'abord, j'ai trouvé la solution à l'exception. Je suis plus curieux pourquoi em> il a généré l'exception spécifique qu'elle l'a fait.

dans mon scénario, j'ajoute un poco à une liste de liste comme: p> xxx pré>

Ceci générait un OutofMemoryException code>. Le problème était que tostring code> hors du poco renvoie null code>. J'ai ajouté un string.isnullorempty code> Vérifiez une valeur "Safe" lorsque NULL et l'exception se sont éloignées. P>

Pourquoi cela génère-t-il un OutofMemoryException code> et Pas quelque chose d'autre (dire un NullReferenceException code>)? p>

EDIT STRY>: Les éléments sont ajoutés dans A pour boucle. p>

pile d'appels complète (Les références spécifiques à la société supprimées) sont ci-dessous. Une chose à noter - la zone de liste est vide lorsque cela s'appelle. P>

System.OutOfMemoryException was unhandled
  Message="List box contains too many items."
  Source="System.Windows.Forms"
  StackTrace:
       at System.Windows.Forms.ListBox.NativeAdd(Object item)
       at System.Windows.Forms.ListBox.ObjectCollection.AddInternal(Object item)
       at System.Windows.Forms.ListBox.ObjectCollection.Add(Object item)
       at <FORM>_Load(Object sender, EventArgs e) in <PATH>\<FORM>.cs:line 52
       at System.Windows.Forms.Form.OnLoad(EventArgs e)
       at System.Windows.Forms.Form.OnCreateControl()
       at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
       at System.Windows.Forms.Control.CreateControl()
       at System.Windows.Forms.Control.WmShowWindow(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       at System.Windows.Forms.ContainerControl.WndProc(Message& m)
       at System.Windows.Forms.Form.WmShowWindow(Message& m)
       at System.Windows.Forms.Form.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.SafeNativeMethods.ShowWindow(HandleRef hWnd, Int32 nCmdShow)
       at System.Windows.Forms.Control.SetVisibleCore(Boolean value)
       at System.Windows.Forms.Form.SetVisibleCore(Boolean value)
       at System.Windows.Forms.Control.set_Visible(Boolean value)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.RunDialog(Form form)
       at System.Windows.Forms.Form.ShowDialog(IWin32Window owner)
       at System.Windows.Forms.Form.ShowDialog()
       at <APP>.Program.Main() in <PATH>\Program.cs:line 25
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
       at System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
       at System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
       at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
       at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
       at System.Activator.CreateInstance(ActivationContext activationContext)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()


5 commentaires

Ajoutez-vous les articles dans une boucle?


Dans quelles circonstances tostring renvoie null? Est-ce quand le Poco est extraordinairement grand?


Par intérêt, pouvez-vous poster la trace de la pile complète de l'exception?


TOSTRING NULL renvoyé parce que j'étais imprudent ... Le poco est fondamentalement seulement 3 cordes.


@AustinSalonen Comment avez-vous réparais cela?


3 Réponses :


10
votes

Lorsque le sous-jacent lb_addstring code> L'appel de l'API Windows échoue, Winforms renvoie toujours un OutofMemoryException code>. Un commentaire dans la source de référence .NET Framework explique pourquoi:

// On some platforms (e.g. Win98), the ListBox control
// appears to return LB_ERR if there are a large number (>32000)
// of items. It doesn't appear to set error codes appropriately,
// so we'll have to assume that LB_ERR corresponds to item 
// overflow.
// 
throw new OutOfMemoryException(SR.GetString(SR.ListBoxItemOverflow)); 


0 commentaires

20
votes

Ceci est à cause de la méthode system.windows.forms.listbox.natienetadd est implémentée: xxx

le getItemtext méthode utilise Tostring () sur l'objet qui retourne null et donc un message est envoyé avec le paramètre null , qui renvoie à son tour un pointeur non valide et que vous entrez dans le deuxième cas qui jette l'exception. < / p>


2 commentaires

HAH, j'allais copier la source entière de la méthode de NativeAjoute dans ma réponse, mais j'ai décidé contre elle ... suppose que j'ai fait le mauvais choix! :-)


@Justin - J'étais déchiré mais je pense que cela aiderait mieux quelqu'un d'autre qui obtient ce problème.



0
votes

Si vous obtenez une telle erreur, vérifiez soigneusement votre code sur lequel vous appelez listbox.items.add code> ou listbox.datasource = xxxxx code>. Quel que soit le type code> objet code> est ajouté ou que la zone de liste doit renvoyer non null dans Tostring () code> méthode. Par défaut .NET renvoie le nom de type si vous ne remplacez pas tostring () code> méthode.

Si vous avez implémenté votre propre version de Tostring () code> (avec mot clé de remplacement) Assurez-vous ensuite que la méthode est échouée sans danger pour renvoyer une chaîne non nulle. Voir l'exemple ci-dessous sur la manière dont vous pouvez ajouter des lignes supplémentaires pour éviter une erreur aussi étrange que de nombreuses personnes trouveront totalement trompeur. P>

//listbox.Items.Add(new MyItem());
//--or--
//listbox.DataSource= new List<MyItem>(){ new MyItem() };

public class MyItem
{
    public string Name { get; set; }
    public string Label { get; set; }

    public override string ToString()
    {
        //Not adding below 2 lines might throw OutOfMemoryException in listbox.Items.Add or listbox.DataSOurce = somelist
        if (string.IsNullOrEmpty(Label)) //Added this check to avoid 
            return this.GetType().Name; //Return string.Empty or something other than null else you will get OutOfMemoryException error when you add or bind this object to listbox

        return Label;
    }
}


0 commentaires