Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 使用MEF进行多次出口确实会造成一些令人发指的后果——为什么,为什么允许这样做?_Wpf_Inversion Of Control_Export_Mef - Fatal编程技术网

Wpf 使用MEF进行多次出口确实会造成一些令人发指的后果——为什么,为什么允许这样做?

Wpf 使用MEF进行多次出口确实会造成一些令人发指的后果——为什么,为什么允许这样做?,wpf,inversion-of-control,export,mef,Wpf,Inversion Of Control,Export,Mef,我有一个有趣的情况,我需要做这样的事情: [Export[typeof(ICandy1)] [Export[typeof(ICandy2)] public class Candy : ICandy2 { ... } 在哪里 public interface ICandy1 { ... } public interface ICandy2 : ICandy1 { ... } 我在任何地方都找不到关于使用多个[Export]属性的帖子,所以我想,见鬼,还是试试吧 乍一看,它实际上似乎起了作用。我

我有一个有趣的情况,我需要做这样的事情:

[Export[typeof(ICandy1)]
[Export[typeof(ICandy2)]
public class Candy : ICandy2 { ... }
在哪里

public interface ICandy1 { ... }
public interface ICandy2 : ICandy1 { ... }
我在任何地方都找不到关于使用多个[Export]属性的帖子,所以我想,见鬼,还是试试吧

乍一看,它实际上似乎起了作用。我有几个方法可以调用Candy实例的两个接口,这很好

然而,当我开始测试应用程序时,我发现行为不正确,当我查看输出窗口时,我发现我收到了大量的ComException。我无法找到它们都来自哪里,但它们总是发生在工作线程睡眠时。我认为它必须来自主线程,但根本不知道如何调试它。GUI中不应该发生任何事情,我禁用了我的调度计时器以防万一——同样的事情

比COMExceptions更奇怪的是,在执行代码时出现了非常非常不稳定的行为。大约30%的时候,当我单步执行时,它会从方法中弹出,或者它会单步执行两行代码!完全奇怪的东西,我不习惯看到

工作代码和非工作代码之间唯一的变化是通过插件加载代码引入了MEF。因此作为测试,我将插件程序集更改为仅导出一个接口,并对应用程序中依赖于另一个(现在未实现)接口的所有内容进行了硬编码。现在ComException消失了,奇怪的调试行为也消失了

这是这里的人以前见过的吗?如果MEF不允许类导出多个接口,那么在编写部件时不应该引发CompositionException吗?有人能解释为什么MEF会引起这些奇怪的问题吗

下面是COMException期间主线程调用堆栈的示例。不确定它是否对任何人都有意义,但如果您能提出任何调试方法,那就太好了

> UIAutomationProvider.dll!MS.Internal.Automation.UiaCoreProviderApi.UiaHostProviderFromHwnd(System.IntPtr hwnd) + 0x38 bytes 
  UIAutomationProvider.dll!System.Windows.Automation.Provider.AutomationInteropProvider.HostProviderFromHandle(System.IntPtr hwnd) + 0x2d bytes 
  PresentationCore.dll!MS.Internal.Automation.ElementProxy.HostRawElementProvider.get() + 0x65 bytes 
  [Native to Managed Transition] 
  [Managed to Native Transition] 
  UIAutomationProvider.dll!System.Windows.Automation.Provider.AutomationInteropProvider.RaiseAutomationPropertyChangedEvent(System.Windows.Automation.Provider.IRawElementProviderSimple element, System.Windows.Automation.AutomationPropertyChangedEventArgs e) + 0x2a bytes 
  PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree() + 0x2c9 bytes 
  PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree() + 0x2f8 bytes 
  PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree() + 0x2f8 bytes 
  PresentationCore.dll!System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree() + 0x2f8 bytes 
  PresentationCore.dll!System.Windows.ContextLayoutManager.fireAutomationEvents() + 0x98 bytes 
  PresentationCore.dll!System.Windows.ContextLayoutManager.UpdateLayout() + 0x65b bytes 
  PresentationCore.dll!System.Windows.ContextLayoutManager.UpdateLayoutCallback(object arg) + 0x19 bytes 
  PresentationCore.dll!System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork() + 0x10 bytes 
  PresentationCore.dll!System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks() + 0x97 bytes 
  PresentationCore.dll!System.Windows.Media.MediaContext.RenderMessageHandlerCore(object resizedCompositionTarget = null) + 0x80 bytes 
  PresentationCore.dll!System.Windows.Media.MediaContext.RenderMessageHandler(object resizedCompositionTarget) + 0x2b bytes 
  WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback = {Method = Cannot evaluate expression because the code of the current method is optimized.}, object args = null, bool isSingleParameter = true) + 0x8a bytes 
  WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source = {System.Windows.Threading.Dispatcher}, System.Delegate callback, object args, bool isSingleParameter, System.Delegate catchHandler = null) + 0x4a bytes 
  WindowsBase.dll!System.Windows.Threading.Dispatcher.WrappedInvoke(System.Delegate callback, object args, bool isSingleParameter, System.Delegate catchHandler) + 0x44 bytes 
  WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl() + 0x5d bytes 
  WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(object state) + 0x38 bytes 
  mscorlib.dll!System.Threading.ExecutionContext.runTryCode(object userData) + 0x51 bytes 
  [Native to Managed Transition] 
  [Managed to Native Transition] 
  mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x67 bytes 
  mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x45 bytes 
  WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke() + 0x63 bytes 
  WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue() + 0x127 bytes 
  WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0x63 bytes 
  WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd = 464158, int msg = 49869, System.IntPtr wParam = 0, System.IntPtr lParam = 0, ref bool handled = false) + 0xbe bytes 
  WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) + 0x7a bytes 
  WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback = {Method = Cannot evaluate expression because the code of the current method is optimized.}, object args = {MS.Win32.HwndSubclass.DispatcherOperationCallbackParameter}, bool isSingleParameter = true) + 0x8a bytes 
  WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source = {System.Windows.Threading.Dispatcher}, System.Delegate callback, object args, bool isSingleParameter, System.Delegate catchHandler = null) + 0x4a bytes 
  WindowsBase.dll!System.Windows.Threading.Dispatcher.WrappedInvoke(System.Delegate callback, object args, bool isSingleParameter, System.Delegate catchHandler) + 0x44 bytes 
  WindowsBase.dll!System.Windows.Threading.Dispatcher.InvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, bool isSingleParameter) + 0x91 bytes 
  WindowsBase.dll!System.Windows.Threading.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority priority, System.Delegate method, object arg) + 0x40 bytes 
  WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd = 464158, int msg = 49869, System.IntPtr wParam = 0, System.IntPtr lParam = 0) + 0xdc bytes 
  [Native to Managed Transition] 
  [Managed to Native Transition] 
  WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame = {System.Windows.Threading.DispatcherFrame}) + 0xc7 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!System.Windows.Application.Run() + 0x19 bytes 

Dan指出,指定两个ExportAttribute可能会从不同的ImportAttribute创建两个实例,但我相信它只创建了一个实例,因为我在Candy的构造函数中设置了一个断点,它只在应用程序的生命周期中被命中。

在一个类上有多个导出是MEF中一个非常正常的用例。我们一直这样做,没有任何问题

丹的话不正确。除非您在导入或导出上显式设置了,否则MEF将更喜欢在容器中重用实例,而不是创建多个实例

您看到的COM异常与MEF无关,因为MEF本身是纯托管的,不使用任何COM互操作。您应该查看COM异常消息及其堆栈跟踪。要在发生此类异常时使调试器中断,请相应地配置visual studio(使用快捷键ctrl+d,e查看相关设置)


您描述的不稳定的调试器行为通常意味着源代码和编译的程序集不匹配。尝试清理bin文件夹,并检查项目之间的依赖关系是否为项目引用,而不是直接的程序集引用。如果依赖项的源代码已更改,则直接程序集引用不会正确触发重建。

我很高兴听到这与MEF无关。奇怪的是,现在我在家里处理相同的代码(我标记了抛出COMExceptions的版本),而它根本没有表现出相同的行为。我将在工作时重新运行代码,并在明天早上尝试获取调用堆栈。感谢您使用部件创建策略清理了所有内容。@Wim:是的,我确实在需要深入研究异常时使用CTRL-D,E。这正是我在办公室得到COMExceptions时所做的,但这是第一次抛出异常时,它没有在抛出异常时切换到线程!!!真奇怪。我明天要做一次大扫除。隐马尔可夫模型。。事实上,我现在就进去看看有什么事。@Wim:你还有其他建议吗?我已经在多个系统上清理、重建、测试过了,这种情况只发生在我的一台机器上!无论我的VS2008选项如何,我都无法让代码在抛出COMException时停止执行。@Dave:1)您有COMException的异常消息吗?2) 您是否使用任何本机代码?3) 你的代码是多线程的吗?我必须再次运行这个测试,但我记得COMException没有给我任何有用的东西。堆栈跟踪也是无用的。我确实有本机代码,因为有第三方DLL,但我不认为有问题的代码(多次导出)正在使用它。我的代码是多线程的,但也不在关注点附近(据我所知)。我会再打给你的!