代码之家  ›  专栏  ›  技术社区  ›  Vilx-

简单C#代码会冻结自身和所有32位应用程序(包括VS2008),但只有在设置了断点的调试器下运行时才会冻结

  •  1
  • Vilx-  · 技术社区  · 15 年前

    作为我正在开发的一个小型winforms应用程序的一部分,我有一个登录屏幕。除了标准用户名/密码字段外,它还有第三个字段-“位置”,这是一个下拉列表,其中包含用户可以登录的可能地理位置。可能位置的列表取决于用户所属的“分发服务器”。把它想象成一个用户群,实际上只不过是这样。

    为了提供用户友好性,每当输入有效用户名时,我都会更改下拉列表的内容。用户名文本框也有自动完成功能。虽然这确实提供了一些信息披露,但在这种情况下,这不是一个问题。

    问题是: 当我在文本框中键入用户名的第一个字母时,autocomplete会立即完成它。下拉列表的内容也应该改变。如果我在没有调试器的情况下运行程序,这种情况会很好发生,但是如果程序处于调试器下,则所有内容都会冻结—包括我的应用程序和VisualStudio。“自动完成”下拉列表出现,但为空。CPU使用率为0%。只有当我关闭我的应用程序时,visualstudio才会解冻。

    private void txtUser_TextChanged(object sender, EventArgs e)
    {
        string EnteredUserName = this.txtUser.Text.Trim();
        var Found = this._NoLocations; 
        foreach ( var usr in this._AllUsers )
            if (string.Compare(usr.FullName, EnteredUserName, StringComparison.CurrentCultureIgnoreCase) == 0)
            {
                Found = new List<Business.Location>(this._AllLocations.Where((a, b) => a.Distributor == usr.Distributor));
                break;
            }
        this.bndLocation.DataSource = Found;
    }
    

    private void txtUser_TextChanged(object sender, EventArgs e)
    {
        string EnteredUserName = this.txtUser.Text.Trim();
        var Found = null; 
        foreach ( var usr in this._AllUsers )
            if (string.Compare(usr.FullName, EnteredUserName, StringComparison.CurrentCultureIgnoreCase) == 0)
            {
                Found = new List<Business.Location>(this._AllLocations.Where((a, b) => a.Distributor == usr.Distributor));
                this.bndLocation.DataSource = Found;
                break;
            }
        if ( Found == null )
            this.bndLocation.DataSource = this._NoLocations;
    }
    

    我也可以在这个方法中设置断点,它会显示这个方法完成得很好,但是冻结发生在之后。

    哦,差点忘了-我正在使用VisualStudio2008和TelerikRadControlsQ32009。windows标准控件没有出现这种情况,只是在迁移之后才出现。不过,还是很奇怪。

    好的,那么第二个代码片段只起作用 有时

    更新2: 变量 _AllUsers _AllLocations _NoLocations 是简单的泛型 List<T> s、 那个 User Location 类是具有简单属性的简单对象。虽然我使用的是NHibernate,所以它们可能是自动的子类。 bndLocation 是标准的.NET BindingSource

    更新3: 哇,很明显 . 或者至少是那些有用户界面的。我可以启动新的应用程序,它们可以初始化并显示出来,但随后它们就冻结了。作为记录,我运行的是Windows7x64。

    更新4: 更新1的关键是:如果代码中没有设置断点,那么代码就可以工作。如果在任何地方设置了断点,它将冻结。断点不需要被命中,只需要设置它。如果我在启动程序后设置断点,一切都会好的。

    更新5:

    ServiceTracker.exe!ServiceTracker.Forms.Login.txtUser_TextChanged(object sender = {Telerik.WinControls.UI.RadTextBox}, System.EventArgs e = {System.EventArgs}) Line 85 C#
    System.Windows.Forms.dll!System.Windows.Forms.Control.OnTextChanged(System.EventArgs e) + 0x68 bytes    
    Telerik.WinControls.UI.dll!Telerik.WinControls.UI.RadTextBoxBase.textBoxItem_TextChanged(object sender = {Telerik.WinControls.UI.RadTextBoxItem}, System.EventArgs e = {System.EventArgs}) + 0x47 bytes 
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    Telerik.WinControls.dll!Telerik.WinControls.RadItem.OnTextChanged(System.EventArgs e = {System.EventArgs}) + 0x80 bytes 
    Telerik.WinControls.dll!Telerik.WinControls.RadItem.OnPropertyChanged(Telerik.WinControls.RadPropertyChangedEventArgs e = {Telerik.WinControls.RadPropertyChangedEventArgs}) + 0xeb bytes   
    Telerik.WinControls.dll!Telerik.WinControls.RadHostItem.OnPropertyChanged(Telerik.WinControls.RadPropertyChangedEventArgs e = {Telerik.WinControls.RadPropertyChangedEventArgs}) + 0x5a bytes   
    Telerik.WinControls.UI.dll!Telerik.WinControls.UI.RadTextBoxItem.OnPropertyChanged(Telerik.WinControls.RadPropertyChangedEventArgs e = {Telerik.WinControls.RadPropertyChangedEventArgs}) + 0x36c bytes 
    Telerik.WinControls.dll!Telerik.WinControls.RadObject.RaisePropertyNotifications(Telerik.WinControls.RadPropertyValue propVal = {Telerik.WinControls.RadPropertyValue}, object oldValue = "", object newValue = "v") + 0x2f7 bytes  
    Telerik.WinControls.dll!Telerik.WinControls.RadObject.SetValueCore(Telerik.WinControls.RadPropertyValue propVal = {Telerik.WinControls.RadPropertyValue}, object propModifier = null, object newValue = "v", Telerik.WinControls.ValueSource source = Local) + 0x5bb bytes  
    Telerik.WinControls.dll!Telerik.WinControls.RadElement.SetValueCore(Telerik.WinControls.RadPropertyValue propVal = {Telerik.WinControls.RadPropertyValue}, object propModifier = null, object newValue = "v", Telerik.WinControls.ValueSource source = Local) + 0xa2 bytes  
    Telerik.WinControls.dll!Telerik.WinControls.RadObject.SetValue(Telerik.WinControls.RadProperty property = {Telerik.WinControls.RadProperty}, object value = "v") + 0x9b bytes   
    Telerik.WinControls.UI.dll!Telerik.WinControls.UI.RadTextBoxItem.TextBoxControl_TextChanged(object sender = {Text = "v"}, System.EventArgs e = {System.EventArgs}) + 0x168 bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Control.OnTextChanged(System.EventArgs e) + 0x68 bytes    
    System.Windows.Forms.dll!System.Windows.Forms.TextBoxBase.WmReflectCommand(ref System.Windows.Forms.Message m) + 0xd2 bytes 
    Telerik.WinControls.UI.dll!Telerik.WinControls.UI.HostedTextBoxBase.WndProc(ref System.Windows.Forms.Message message = {msg=0x2111 (WM_REFLECT + WM_COMMAND) hwnd=0xf0478 wparam=0x3000478 lparam=0xf0478 result=0x0}) + 0x5ac bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x46 bytes  
    System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg = 8465, System.IntPtr wparam, System.IntPtr lparam) + 0xad bytes  
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    System.Windows.Forms.dll!System.Windows.Forms.Control.SendMessage(int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x6c bytes 
    System.Windows.Forms.dll!System.Windows.Forms.Control.ReflectMessageInternal(System.IntPtr hWnd, ref System.Windows.Forms.Message m) + 0x46 bytes   
    System.Windows.Forms.dll!System.Windows.Forms.Control.WmCommand(ref System.Windows.Forms.Message m) + 0x44 bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x1fd bytes 
    Telerik.WinControls.dll!Telerik.WinControls.RadControl.WndProc(ref System.Windows.Forms.Message m = {msg=0x111 (WM_COMMAND) hwnd=0xc046e wparam=0x3000478 lparam=0xf0478 result=0x0}) + 0x1ab bytes 
    Telerik.WinControls.UI.dll!Telerik.WinControls.UI.RadTextBoxBase.WndProc(ref System.Windows.Forms.Message m = {msg=0x111 (WM_COMMAND) hwnd=0xc046e wparam=0x3000478 lparam=0xf0478 result=0x0}) + 0x7a bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x46 bytes  
    System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg = 273, System.IntPtr wparam, System.IntPtr lparam) + 0xad bytes   
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) + 0x9f bytes  
    System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x9e6 bytes 
    Telerik.WinControls.UI.dll!Telerik.WinControls.UI.HostedTextBoxBase.WndProc(ref System.Windows.Forms.Message message = {msg=0x102 (WM_CHAR) hwnd=0xf0478 wparam=0x76 lparam=0x2f0001 result=0x0}) + 0x5ac bytes 
    System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x46 bytes  
    System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg = 258, System.IntPtr wparam, System.IntPtr lparam) + 0xad bytes   
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int dwComponentID, int reason, int pvLoopData) + 0x5c3 bytes  
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = 4, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.Application.ModalApplicationContext}) + 0x578 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x65 bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window owner) + 0x763 bytes    
    ServiceTracker.exe!ServiceTracker.Forms.Login.Authentificate(out ServiceTracker.Business.User user = null, out ServiceTracker.Business.Location location = null) Line 30 + 0x12 bytes   C#
    ServiceTracker.exe!ServiceTracker.Framework.Program.Main() Line 79 + 0x19 bytes C#
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x47 bytes  
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x9b bytes    
    mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x4d bytes   
    

    更新6: 所以,我甚至强烈怀疑我的应用程序和其他32位应用程序之间存在死锁和竞争条件的组合。这很奇怪,因为即使在调试器下,进程也是64位的。不管怎样,以下是重现问题的几种可能的情况:

    • 这个方法改变了下拉列表的内容,在我的代码中任何地方都有一个断点。但是如果断点在 if
    • 如果 声明,一切也都冻结了。
    • 如果方法只包含 Thread.Sleep(1000); ,冻结时间正好为1秒;

    但是。。。我无法想象这个全球资源会是什么。

    2 回复  |  直到 15 年前
        1
  •  1
  •   tster    15 年前

    我不知道你的问题是什么,但我可以指出你正在做的一些可能会引起问题的事情:

    1. 在lambda表达式中访问修改的闭包:

    我觉得这不是你的问题。要查看是否是,请执行以下操作:

    var usrTemp = usr;
    Found = new List<Business.Location>(this._AllLocations.Where((a, b) => a.Distributor == usrTemp.Distributor));
    
    1. 我不知道您使用的是哪种LINQ提供程序,或者您的OnItemBound事件是什么样子的,但是在第一个示例中,当您在\u AllUsers上仍然有一个迭代器打开时,您正在投标您的项目。如果您的业务层不支持这种并发访问,这可能会导致问题。

    foreach (var usr in this._AllUsers.ToArray())
    
        2
  •  0
  •   Alien    7 年前

    this.bndLocation.DataSource ?