开发者

WPF - Random hanging with file browser attached behaviour

开发者 https://www.devze.com 2022-12-14 04:50 出处:网络
I have an attached behavior defined thusly,.. public static class FileBrowserBehaviour { public static bool GetBrowsesOnClick(DependencyObject obj)

I have an attached behavior defined thusly,..

    public static class FileBrowserBehaviour
{


    public static bool GetBrowsesOnClick(DependencyObject obj)
    {
        return (bool)obj.GetValue(BrowsesOnClickProperty);
    }

    public static void SetBrowsesOnClick(DependencyObject obj, bool value)
    {
        obj.SetValue(BrowsesOnClickProperty, value);
    }

    // Using a DependencyProperty as the backing store for BrowsesOnClick.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty BrowsesOnClickProperty =
        DependencyProperty.RegisterAttached("BrowsesOnClick", typeof(bool), typeof(FileBrowserBehaviour), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(BrowsesOnClickChanged)));


    public static void BrowsesOnClickChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        FrameworkElement fe = obj as FrameworkElement;

        if ((bool)args.NewValue)
        {
            fe.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(OpenFileBrowser);
        }
        else
        {
            fe.PreviewMouseLeftButtonDown -= new MouseButtonEventHandler(OpenFileBrowser);
        }
    }

    static void OpenFileBrowser(object sender, MouseButtonEventArgs e)
    {
        var tb = sender as TextBox;
        if (tb.Text.Length < 1 || tb.Text=="Click to browse..")
        {
            OpenFileDialog ofd = new OpenFileDialog();
                ofd.Filter = "Executables | *.exe";
                if (ofd.ShowDialog() == true)
                {
                    Debug.WriteLine("Setting textbox text-" + ofd.FileName);
                    tb.Text = ofd.FileName;
                    Debug.WriteLine("Set textbox text");
                }
        }
    }
}

It's a nice simple attached behavior which pops open an OpenFileDialog when you click on a textbox and puts the filename in the box when you're done.

It works maybe 40% of the time but the rest of the time the whole app hangs. The call stack at this point looks like this -

[Managed to Native Transition]  

WindowsBase.dll!MS.Win32.UnsafeNativeMethods.GetMessageW(ref System.Windows.Interop.MSG msg, System.Runtime.InteropServices.HandleRef hWnd, int uMsgFilterMin, int uMsgFilterMax) + 0x15 bytes

WindowsBase.dll!System.Windows.Threading.Dispatcher.GetMessage(ref System.Windows.Interop.MSG msg, System.IntPtr hwnd, int minMessage, int maxMessage) + 0x48 bytes WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame = {System.Windows.Threading.DispatcherFrame}) + 0x8b bytes WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) + 0x49 bytes

WindowsBase.dll!System.Windows.Threading.Dispatcher.Run() + 0x4c bytes

PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) + 0x1e bytes

PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) + 0x6f bytes PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window) + 0x26 bytes PresentationFramework.dll!Sy开发者_开发知识库stem.Windows.Application.Run() + 0x19 bytes Debugatron.exe!Debugatron.App.Main() + 0x5e bytes C# [Native to Managed Transition]

[Managed to Native Transition]

mscorlib.dll!System.AppDomain.nExecuteAssembly(System.Reflection.Assembly assembly, string[] args) + 0x19 bytes mscorlib.dll!System.Runtime.Hosting.ManifestRunner.Run(bool checkAptModel) + 0x6e bytes mscorlib.dll!System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly() + 0x84 bytes mscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext, string[] activationCustomData) + 0x65 bytes mscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext) + 0xa bytes mscorlib.dll!System.Activator.CreateInstance(System.ActivationContext activationContext) + 0x3e bytes

Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone() + 0x23 bytes

mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x66 bytes

mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x6f bytes

mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes

Now, I've seen this kind of thing before when doing some asynchronous stuff but there's none of that going on at that point. The only thread alive is the UI thread! Also, I always get that last debug statement when it does hang.

Can anyone point me in the right direction? This one's driving me crazy!


I have a very simple WPF application that uses the WPF WebBrowser control in a WPF application. I have exactly the same problem. The WPF WebBrowser control (with Google Earth launched using JavaScript) freezes about 75% of the time when I resize the window horizontally. I get the exact same stack dump as listed above. When I copy/run the executable on a different PC (all running XP SP3) it runs fine and never hangs. I also have a more complex app that is multi-threaded which also hangs with a similar stack dump (also waiting on a message inside the Threading library) on this PC but not another PC. The WPF WebBrowser control app has the same problem whether it is targeted for .Net 3.5 or 4.0. I used NETfx_Setupverifier to verify the .net installations are correct, but I still suspect there is an issue with either .net or some COM utility that is causing the .NET - COM interop to be unstable. It is also my guess that my app is waiting on some unmanaged event/message that never arrives because of a problem with the interop. I also wrote the same simple app using WinForms/WinForm WebBrowser Control and that app never hangs on the same PC.

Does anyone have any suggestions on how to track down the cause? I'm thinking about completely uninstalling/reinstalling the .NET frameworks even though they were verified correct. I don't even know where to look for anomalies on the COM side.


Here goes some almost random facts and questions, that might help you.

First of all, I couldn't reproduce your problem. No matter how much I tried. It always worked.

Stack trace also looks good for me: it keeps processing messages loop. What exactly confuses you? Managed to native transition?

You can't have one thread in WPF application. What do you see in the Threads window in VS Debugger?

When I hit break all I see the call to ofd.ShowDialog() in the main thread stack trace, and one worker thread named .NET SystemEvents stays in WindowThreadProc(), waiting on a sync object. What do you see?

It looks like you got into deadlock somehow.

Try wrap OpenFileBrowser() contents into try... catch{}. Are there any errors?

0

精彩评论

暂无评论...
验证码 换一张
取 消