0

我在 .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 扫描仪扫描数据时,我有一个基本类要处理。在该课程中,我有一个要在扫描数据时触发的事件。这是一个片段:

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”?

我使用棱镜,所以一些模块在运行时加载(在我的输出目录的子文件夹中)......包括我使用上面最后一个代码片段的那个(Scanner = PosHelper.GetHardware ....)

4

1 回答 1

0

I believe I solved my problem. Since my prism modules are loaded at runtime within a subdirectory I needed to add this to the AppDomain so that the AppDomain could find the assemblies in the subdirectories folder.:

PrivateBinPath = @"Modules"

http://msdn.microsoft.com/en-us/library/system.appdomainsetup.privatebinpath.aspx

Edit

This only partially solved my problem. I also had to override InitializeLifetimeService() and return null so that my MarshalByRefObject's would not be disposed while the program is running (I believe the default timeout is 5 minutes).

Also , this now works:

Scanner.DataScanned += m =>
    {
        Debug.WriteLine(m);
    }

but when I try something like this

Scanner.DataScanned += m =>
    {
        DoSomething(m);
    }

Where DoSomething is not in a Serializable and MarshalByRefObject class, it craps out since all classes that are used in the communication between AppDomain's need to have those. So where I'm at now is looking at using WCF named pipes to pass data around... and other similar solutions.

于 2012-09-05T02:32:08.713 回答