【发布时间】:2012-09-05 01:19:00
【问题描述】:
我在 .Net 的 POS 中使用以下帮助程序类来获取对单独 AppDomain 中硬件的引用(绕过需要 <NetFx40_LegacySecurityPolicy enabled="true"/> 的一些限制
public static class PosHelper
{
private static AppDomain _posAppDomain { get; set; }
private static AppDomain PosAppDomain
{
get
{
if (_posAppDomain == null)
{
AppDomainSetup currentAppDomainSetup = AppDomain.CurrentDomain.SetupInformation;
AppDomainSetup newAppDomainSetup = new AppDomainSetup()
{
ApplicationBase = currentAppDomainSetup.ApplicationBase,
LoaderOptimization = currentAppDomainSetup.LoaderOptimization,
ConfigurationFile = currentAppDomainSetup.ConfigurationFile
};
newAppDomainSetup.SetCompatibilitySwitches(new[] { "NetFx40_LegacySecurityPolicy" });
_posAppDomain = AppDomain.CreateDomain("POS Hardware AppDomain", null, newAppDomainSetup);
}
return _posAppDomain;
}
}
public static T GetHardware<T>() where T : PosHardware, new()
{
T hardware = (T)PosAppDomain.CreateInstanceFromAndUnwrap(Assembly.GetAssembly(typeof(T)).Location, typeof(T).FullName);
hardware.FindAndOpenDevice();
return hardware;
}
}
当 POS 扫描仪扫描数据时,我有一个基本类要处理。在该课程中,我有一个要在扫描数据时触发的事件。这是一个sn-p:
public class ScannerDevice : PosHardware
{
public event Action<string> DataScanned;
...
_scanner.DataEvent += new DataEventHandler(Scanner_DataEvent);
...
private void Scanner_DataEvent(object sender, DataEventArgs e)
{
ASCIIEncoding encoder = new ASCIIEncoding();
if (DataScanned != null)
DataScanned(encoder.GetString(_scanner.ScanDataLabel));
_scanner.DataEventEnabled = true; // enable for subsequent scans
}
请注意,PosHardware 抽象类继承 MarshalByRefObject 并标记为 [Serializable]
在我的主 AppDomain 中,我尝试像这样使用事件:
Scanner = PosHelper.GetHardware<ScannerDevice>();
Scanner.DataScanned += m =>
{
Debug.WriteLine(m);
};
当它遇到尝试将 lambda 添加到 DataScanned 事件的行时,我收到此错误:
无法加载文件或程序集 'MyAssemlyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' 或其依赖项之一。这 系统找不到指定的文件。
这必须与尝试在 AppDomain 之间进行通信有关。不太确定该怎么做。我需要在用于 Pos for .Net 的单独 AppDomain 中注册“MyAssemblyName”吗?
我使用 prism,因此在运行时会加载一些模块(在我的输出目录的子文件夹中)...包括我使用上面最后一个代码 sn-p 的那个(Scanner = PosHelper.GetHardware .... )
【问题讨论】:
-
顺便说一句,我认为您不应该在 MarshalByRefObject 上添加可序列化属性。可序列化对象应该是从一个 AppDomain 传递到另一个的对象。基于 MarshalByRefObject 的对象保留在其 AppDomain 上,并且整个通信是通过 .NET Remoting 机制透明创建的代理对象进行的。
标签: prism appdomain marshalbyrefobject pos-for-.net