繁体   English   中英

为什么此代码仅在从Visual Studio内部运行时才起作用?

[英]Why does this code only work when run from inside Visual Studio but not otherwise?

当我在Visual Studio中按F5键(同时具有Debug或Release版本)时,我有下面的代码可以正常工作,但是当我直接运行EXE文件时,出现异常:

    System.InvalidOperationException: 未能比较数组中的两个元素。 ---> System.ArgumentException: Hey,C#,you give me a null?
   在 GeometricComposition.GCForm.DataForm.<>c__DisplayClass3.<GenerateTreeNodes>b__1(TreeNode a, TreeNode b) 位置 h:\Projects\C#\GeometricComposition\GeometricComposition\GCForm\DataFormGenerateDistance.cs:行号 124
   在 System.Array.FunctorComparer`1.Compare(T x, T y)
   在 System.Collections.Generic.ArraySortHelper`1.PickPivotAndPartition(T[] keys, Int32 lo, Int32 hi, IComparer`1 comparer)
   在 System.Collections.Generic.ArraySortHelper`1.IntroSort(T[] keys, Int32 lo, Int32 hi, Int32 depthLimit, IComparer`1 comparer)
   在 System.Collections.Generic.ArraySortHelper`1.IntroSort(T[] keys, Int32 lo, Int32 hi, Int32 depthLimit, IComparer`1 comparer)
   在 System.Collections.Generic.ArraySortHelper`1.IntroSort(T[] keys, Int32 lo, Int32 hi, Int32 depthLimit, IComparer`1 comparer)
   在 System.Collections.Generic.ArraySortHelper`1.IntrospectiveSort(T[] keys, Int32 left, Int32 length, IComparer`1 comparer)
   在 System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
   --- 内部异常堆栈跟踪的结尾 ---
   在 System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
   在 System.Array.Sort[T](T[] array, Int32 index, Int32 length, IComparer`1 comparer)
   在 System.Collections.Generic.List`1.Sort(Comparison`1 comparison)
   在 GeometricComposition.GCForm.DataForm.GenerateTreeNodes(String rootFormat, String childFormat, FuncRef`3 getChildNodes, Func`3 comparePairs) 位置 h:\Projects\C#\GeometricComposition\GeometricComposition\GCForm\DataFormGenerateDistance.cs:行号 121
   在 GeometricComposition.GCForm.DataForm.DisplayPairsTreeInvoke() 位置 h:\Projects\C#\GeometricComposition\GeometricComposition\GCForm\DataFormGenerateDistance.cs:行号 100
   在 GeometricComposition.GCForm.DataForm.GenerateData(GCFile file) 位置 h:\Projects\C#\GeometricComposition\GeometricComposition\GCForm\DataForm.cs:行号 44
   在 GeometricComposition.GCForm.DataForm.HandleSelectedFileChanged(Object sender, SelectedFileChangedEventArg e) 位置 h:\Projects\C#\GeometricComposition\GeometricComposition\GCForm\DataForm.cs:行号 73
   在 GeometricComposition.SelectedFileChangedEventHandler.Invoke(Object sender, SelectedFileChangedEventArg e)
   在 GeometricComposition.MainForm.OnSelectedFileChanged() 位置 h:\Projects\C#\GeometricComposition\GeometricComposition\MainForm.cs:行号 68
   在 GeometricComposition.MainForm.WorkDockPanel_ActiveContentChanged(Object sender, EventArgs e) 位置 h:\Projects\C#\GeometricComposition\GeometricComposition\MainForm.cs:行号 59
   在 WeifenLuo.WinFormsUI.Docking.DockPanel.OnActiveContentChanged(EventArgs e) 位置 h:\Projects\C#\GeometricComposition\WinFormsUI\Docking\DockPanel.FocusManager.cs:行号 577
   在 WeifenLuo.WinFormsUI.Docking.DockPanel.FocusManagerImpl.RefreshActiveWindow() 位置 h:\Projects\C#\GeometricComposition\WinFormsUI\Docking\DockPanel.FocusManager.cs:行号 402
   在 WeifenLuo.WinFormsUI.Docking.DockPanel.FocusManagerImpl.HookEventHandler(Object sender, HookEventArgs e) 位置 h:\Projects\C#\GeometricComposition\WinFormsUI\Docking\DockPanel.FocusManager.cs:行号 354
   在 WeifenLuo.WinFormsUI.Docking.DockPanel.FocusManagerImpl.LocalWindowsHook.OnHookInvoked(HookEventArgs e) 位置 h:\Projects\C#\GeometricComposition\WinFormsUI\Docking\DockPanel.FocusManager.cs:行号 58
   在 WeifenLuo.WinFormsUI.Docking.DockPanel.FocusManagerImpl.LocalWindowsHook.CoreHookProc(Int32 code, IntPtr wParam, IntPtr lParam) 位置 h:\Projects\C#\GeometricComposition\WinFormsUI\Docking\DockPanel.FocusManager.cs:行号 78
   在 System.Windows.Forms.UnsafeNativeMethods.SetFocus(HandleRef hWnd)
   在 System.Windows.Forms.ContainerControl.FocusActiveControlInternal()
   在 System.Windows.Forms.Form.set_Active(Boolean value)
   在 System.Windows.Forms.Form.WmActivate(Message& m)
   在 System.Windows.Forms.Form.WndProc(Message& m)
   在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

这不是我第一次或遇到此问题的项目,但是这次我决定找出原因。

完整的原始代码是:

...
...
GenerateTreeNodes("P", "FD", GetChildNodesByPitch, ComparePairsDistance);
...
...
private void GenerateTreeNodes(string rootFormat, string childFormat,
        FuncRef<int, string, List<TreeNode>> getChildNodes,
        Func<GCFacePointPair, GCFacePointPair, int> comparePairs)
    {
        int i = 0;
        while (i < fpps.Count)
        {
            TreeNode rootNode = new TreeNode(fpps[i].ToString(rootFormat));
            List<TreeNode> childNodes = getChildNodes(ref i, childFormat);
            childNodes.Sort((TreeNode a, TreeNode b) =>
            {
                if (a == null || b == null)
                    throw new ArgumentNullException("Hey,C#,you give me a null?");
                return comparePairs((GCFacePointPair)a.Tag, (GCFacePointPair)b.Tag);
            });
            rootNode.Nodes.AddRange(childNodes.ToArray());
            FacePointTreeView.Invoke((Func<TreeNode, int>)(FacePointTreeView.Nodes.Add), rootNode);
        }
    }

    private List<TreeNode> GetChildNodesByPitch(ref int index, string format)
    {
        List<TreeNode> childNodes = new List<TreeNode>();
        GCPitch curr = fpps[index].Point.ID;
        while (index < fpps.Count && fpps[index].Point.ID == curr)
        {
            TreeNode node = new TreeNode(fpps[index].ToString(format));
            node.Tag = fpps[index];
            childNodes.Add(node);
            index++;
        }
        return childNodes;
    }

    private int ComparePairsDistance(GCFacePointPair a, GCFacePointPair b)
    { return Math.Sign(a.Distance - b.Distance); }

问题是在Sort()之前,在childNodes没有null但在Sort()我得到了null


显然,必须设置Tag属性。


  1. 它为我的比较提供了一个空值。 为什么?

  2. 如代码所示,在调用Sort()之前, childNodes没有空值,但在Sort() ,则存在空值。 为什么?

  3. 调试版本和发布版本之间有什么区别?

4.是C#错误吗? 我之前遇到过C#错误。

您的代码检查是否有任何空的TreeNodes。 但是,它也将TreeNode.Tag强制转换为GCFacePointPair:

return comparePairs((GCFacePointPair)a.Tag, (GCFacePointPair)b.Tag);

我怀疑可能存在尚未设置标签的TreeNodes。 也许您应该添加测试,以帮助您调试以下内容:

        if (childNodes.FindIndex((TreeNode n) => 
            { return n == null; }) != -1)
            throw new Exception("null 0");
        if (childNodes.FindIndex((TreeNode n) => { 
            return !(n.Tag is GCFacePointPair); }) != -1)
            throw new Exception("Tag not set");

好吧,我已经解决了这个问题...虽然我仍然不知道为什么...我保证我的代码中没有错误...如何解决? 这是代码:

...
...
GenerateTreeNodes("P", "FD", GetChildNodesByPitch, ComparePairsDistance);
...
...
private void GenerateTreeNodes(string rootFormat, string childFormat,
            ActionRef2<SortedSet<TreeNode>,int, string> getChildNodes,
            Func<GCFacePointPair, GCFacePointPair, int> comparePairs)
        {
            int index = 0;
            while (index < fpps.Count)
            {
                TreeNode rootNode = new TreeNode(fpps[index].ToString(rootFormat));
                SortedSet<TreeNode> childNodes =
                    new SortedSet<TreeNode>(
                        Comparer<TreeNode>.Create((TreeNode a, TreeNode b) =>
                        {
                            return comparePairs((GCFacePointPair)a.Tag, (GCFacePointPair)b.Tag);
                        }));

                getChildNodes(ref childNodes, ref index, childFormat);

                /*childNodes.Sort((TreeNode a, TreeNode b) =>
                {
                    return comparePairs((GCFacePointPair)a.Tag, (GCFacePointPair)b.Tag);
                });*/

                TreeNode[] nodes = new TreeNode[childNodes.Count];
                childNodes.CopyTo(nodes);
                rootNode.Nodes.AddRange(nodes);
                //rootNode.Nodes.AddRange(childNodes.ToArray());

                FacePointTreeView.Invoke((Func<TreeNode, int>)(FacePointTreeView.Nodes.Add), rootNode);
            }
        }

        private void GetChildNodesByPitch(ref SortedSet<TreeNode> childNodes, ref int index, string format)
        {
            GCPitch curr = fpps[index].Point.ID;
            while (index < fpps.Count && fpps[index].Point.ID == curr)
            {
                TreeNode node = new TreeNode(fpps[index].ToString(format));
                node.Tag = fpps[index];
                childNodes.Add(node);
                index++;
            }
        }

        private int ComparePairsDistance(GCFacePointPair a, GCFacePointPair b)
        { return Math.Sign(a.Distance - b.Distance); }

注意,我只是将List<T>替换为SortedSet<T>并进行一些调整,因此在Add所有节点之后,将对它进行排序。

我仍然不知道发布版本中会发生什么...谁可以帮助我?

要找出错误的地方,请检查可能错误的节点的值

var nullIdx = childNodes.FindIndex((TreeNode n) => { return n == null; });
if (nullIdx >= 0)
{
    var nullChild = childNodes[nullIdx];
    // todo nullIdx-1 and nullIdx+1 to maybe check what went wrong
    throw new Exception("null 1");
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM