WPF - pendurado aleatório com o comportamento anexado do navegador
-
20-09-2019 - |
Pergunta
Eu tenho um comportamento anexado definido assim, ..
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");
}
}
}
}
É um bom comportamento simples em anexo que abre um OpenFiledialog quando você clica em uma caixa de texto e coloca o nome do arquivo na caixa quando terminar.
Funciona talvez 40% das vezes, mas o resto do tempo todo o aplicativo está pendurado. A pilha de chamadas neste momento se parece com isso -
[Managed to Native Transition]
Windowsbase.dll! Ms.win32.unsafenativemethods.getMessagew (ref System.windows.interop.msg msg, system.runtime.interropservices.handleref hwnd, intmsgfiltermin, intmsgfiltermAx) + 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! PushframeImpl (system.windows.threading.dispatcherframe quadro = {system.windows.threading.dispatcherframe}) + 0x8b bytes windowsbase.dll! System.windows.threading.dispatcher.pushframe (system.windows.thead.dispcherfReading.dispatcher.pushframe (system.windows.thesting.dispcherfReading.dispatcher.pushframe (system.windows.thesting.dispcherfReading.dispatcher.pushframe (system.windows.thesting.dispcherfReading)
Windowsbase.dll! System.windows.threading.dispatcher.run () + 0x4c bytes
ApresentationFramework.dll! System.windows.application.rundispatcher (Objeto ignore) + 0x1e bytes
PresentationFramework.dll! System.Windows.Application.Runinternal (System.Windows.Window Window) + 0x6f Bytes PresentationFramework.dll! Windows.Application.run () + 0x19 bytes debugatron.exe! Debugatron.app.main () + 0x5e bytes c# [nativo para transição gerenciada
Gerenciado para transição nativa
mscorlib.dll! System.AppDomain.NexecteseSeSMBLY (System.Reflection.ASSEMMBLY Assembléia, String [] args) + 0x19 bytes mscorlib.dll! System.Runtime.Hosting.Manifestrunner.Run (BOOL checkaptModel) + 0x6e bytes m mll ml! .Runtime.Hosting.ManifeSTUNNER.EXECONDEASASSEMBLY () + 0x84 bytes mscorlib.dll! System.Runtime.Hosting.ApplicationActivator.CreateInstance (System.ActivationContextTationContext, String [] SIGNOCUSTOMDOMDATA! 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 (estado de objeto) + 0x66 bytes
mscorlib.dll! system.threading.executioncontext.run (system.threading.executionContext ExecutionContext, system.threading.contextCallback de chamada, estado de objeto) + 0x6f bytes
mscorlib.dll! System.threading.threadhelper.threadstart () + 0x44 bytes
Agora, eu já vi esse tipo de coisa antes quando fazia algumas coisas assíncronas, mas não há nada disso acontecendo naquele momento. O único fio vivo é o tópico da interface do usuário! Eu também sempre Obtenha a última declaração de depuração quando ele estiver.
Alguém pode me apontar na direção certa? Este está me deixando louco!
Solução
Eu tenho um aplicativo WPF muito simples que usa o controle WPF WebBrowser em um aplicativo WPF. Eu tenho exatamente o mesmo problema. O controle WPF WebBrowser (com o Google Earth lançado usando JavaScript) congela cerca de 75% das vezes em que redimenso a janela horizontalmente. Recebo exatamente o mesmo despejo de pilha listado acima. Quando copio/executo o executável em um PC diferente (todos em execução XP SP3), ele funciona bem e nunca pendura. Eu também tenho um aplicativo mais complexo que é multi-thread, que também fica com um despejo de pilha semelhante (também aguardando uma mensagem dentro da biblioteca de threading) neste PC, mas não em outro PC. O aplicativo WebBrowser Control do WPF tem o mesmo problema, seja direcionado para .NET 3.5 ou 4.0. Eu usei netfx_setupVerriFier para verificar se as instalações do .NET estão corretas, mas ainda suspeito que haja um problema no .NET ou a algum utilitário que está fazendo com que a interop .NET - com seja instável. Também é possível que meu aplicativo esteja aguardando algum evento/mensagem não gerenciado que nunca chegue por causa de um problema com a interop. Eu também escrevi o mesmo aplicativo simples usando o controle WebForms/Winform WebBrowser e esse aplicativo nunca pendura no mesmo PC.
Alguém tem alguma sugestão sobre como rastrear a causa? Estou pensando em desinstalar/reinstalar completamente as estruturas .NET, embora tenham sido verificadas corretas. Eu nem sei onde procurar anomalias no lado com.
Outras dicas
Aqui vão alguns fatos e perguntas quase aleatórios, isso pode ajudá -lo.
Primeiro de tudo, não pude reproduzir seu problema. Não importa o quanto eu tentei. Sempre funcionou.
O Stack Trace também parece bom para mim: continua processando as mensagens loop. O que exatamente confunde você? Conseguiu transição nativa?
Você não pode ter um thread no aplicativo WPF. O que você vê na janela Threads no vs depurador?
Quando clico em Break, vejo a chamada para OFD.ShowDialog () no rastreamento da pilha de threads principal, e um thread de trabalhador chamado .NET SystemEvents permanece no WindowThreadProc (), esperando um objeto de sincronização. O que você vê?
Parece que você entrou em impasse de alguma forma.
Tente envolver OpenFileBrowser()
conteúdo em try... catch{}
. Existem erros?