WPF - ランダムなファイルブラウザ付属の行動にぶら下がっ
-
20-09-2019 - |
質問
私は..
、添付の挙動は以下のようなものを定義してい 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");
}
}
}
}
それはあなたがテキストボックスをクリックしたときに開いOpenFileDialogをポップし、完了したら、ボックスにファイル名を置く素敵なシンプルな添付行動です。
これは多分40%の時間が、全体のアプリがハングアップし、残りの時間を動作します。この時点でのコールスタックは、次のようになります -
[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のバイト
WindowsBase.dll!System.Windows.Threading.Dispatcher.GetMessage(REF System.Windows.Interop.MSG MSG、System.IntPtr HWND、int型minMessage、int型maxMessage)+ 0x48バイト WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrameフレーム= {System.Windows.Threading.DispatcherFrame})+ 0x8bバイト WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrameフレーム)+ 0x49バイト
WindowsBase.dll!System.Windows.Threading.Dispatcher.Run()+ 0x4cバイト
PresentationFramework.dll!System.Windows.Application.RunDispatcher(オブジェクトは無視)+ 0x1eが表示バイト
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Windowウィンドウ)+ 0x6fバイト PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Windowウィンドウ)+ 0x26バイト PresentationFramework.dll!System.Windows.Application.Run()+ 0x19バイト Debugatron.exe!Debugatron.App.Main()+ 0x5EのバイトのC# [管理への移行ネイティブ]
[ネイティブの移行への管理対象] がmscorlib.dll!System.AppDomain.nExecuteAssembly(System.Reflection.Assemblyアセンブリ、文字列[] argsを)+ 0x19バイト 0x6eバイト+!System.Runtime.Hosting.ManifestRunner.Run(ブール値checkAptModel)のMscorlib.dll がmscorlib.dll!System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()+ 0x84のバイト がmscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext、文字列[] activationCustomData)+ 0x65バイト がmscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext)+は0xaバイト がmscorlib.dll!System.Activator.CreateInstance(System.ActivationContext activationContext)+ 0x3eバイト
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()+ 0x23バイト
がmscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(オブジェクトの状態)+は0x66バイト
がmscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContextのExecutionContext、System.Threading.ContextCallbackコールバック、オブジェクトの状態)+ 0x6fバイト
がmscorlib.dll!System.Threading.ThreadHelper.ThreadStart()+ 0x44のバイト
さて、私はいくつかの非同期のものをやったときに前にこの種のものを見てきましたが、それはその時点で起こっているのどれもありません。生きているだけのスレッドは、UIスレッドです!また、私は常にのそれがハングしないよう、最後のデバッグ文を取得します。
誰もが正しい方向に私を指すことができますか?この1の狂気私を運転!
解決
私は、WPFアプリケーションでWPFのWebBrowserコントロールを使用して、非常に単純なWPFアプリケーションを持っています。私は正確に同じ問題を抱えています。 WPFのWebBrowserコントロール私は水平にウィンドウのサイズを変更すると、時間の約75%をフリーズ(Google EarthではJavaScriptを使用して起動しました)。上記のように私はまったく同じスタックダンプを取得します。私は(すべてがXP SP3を実行している)別のPC上で実行可能ファイルを実行する/コピーするとそれが正常に実行され、決してハングアップします。私はまた、このPC上で同様のスタックダンプ(また、スレッドライブラリ内のメッセージを待っている)ではなく、別のPCでハングアップされたマルチスレッド化され、より複雑なアプリを持っています。 WPFのWebBrowserコントロールアプリは、それは.NET 3.5または4.0を対象としているかどうか、同じ問題を抱えています。私は、.NETのインストールが正しいことを確認するためにNETfx_Setupverifierを使用し、私はまだ.NETまたは.NETを引き起こしているいくつかのCOMユーティリティのいずれかに問題がある疑いがある - COM相互運用不安定には。それは私のアプリが原因で相互運用に問題が到着したことがないいくつかの管理対象外のイベント/メッセージを待っていることも私の推測です。私はまた、リサイズ/ WinフォームのWebBrowserコントロールを使用して同じシンプルなアプリを書いて、そのアプリが同じPC上でハングアップすることはありません。
誰もが原因を追跡する方法上の任意の提案を持っていますか?私は完全にアンインストール/それらが正しい確認したにもかかわらず、.NETフレームワークを再インストールすることを考えています。私もCOM側の異常を探すためにどこか分からない。
他のヒント
ここであなたを助けるかもしれないいくつかのほとんどのランダムな事実との質問に、行きます。
まず第一に、私はあなたの問題を再現できませんでした。私が試したどんなに。それは常に働きました。
スタックトレースも私にとってはよさそうだ:それはメッセージの処理ループを保持します。正確にあなたは何を混乱させる?ネイティブの遷移にマネージド?
あなたは、WPFアプリケーション内の1つのスレッドを持つことはできません。あなたはVSデバッガのスレッドのウィンドウには何を見ていますか?
私はメインスレッドのスタックトレースでofd.ShowDialog()の呼び出しを参照すべてを破るヒットする場合、および.NET SystemEventsという名前の1つのワーカースレッドが同期オブジェクト上で待機している、)WindowThreadProc(にとどまります。あなたは何を見ていますか?
あなたは何とかデッドロックに入ったように、に見えます。
OpenFileBrowser()
にラップtry... catch{}
の内容をお試しください。何らかのエラーがありますか。