- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个 Windows 服务,它在运行时在另一个 AppDomain 中加载程序集。然后执行它们并最终卸载 AppDomain。问题是插件的执行方法是异步任务,我得到了 SerializationException,因为 Task 没有继承自 MarshalByRefObject。
我将插件包装在继承自 MarshalByRefObject 的代理中,但我不知道如何摆脱 SerializationException?
public interface IPlugin : IDisposable
{
Guid GUID { get; }
string Name { get; }
string Description { get; }
Task Execute(PluginPanel panel, string user);
}
代理:
[Serializable()]
public class PluginProxy : MarshalByRefObject, IPlugin
{
private IPlugin m_Plugin;
public bool Init(string file)
{
Assembly ass = Assembly.Load(AssemblyName.GetAssemblyName(file));
if (ass == null || ass.GetTypes() == null || ass.GetTypes().Length == 0)
return false;
foreach (Type type in ass.GetTypes())
{
if (type.IsInterface || type.IsAbstract)
continue;
if (type.GetInterface(typeof(IPlugin).FullName) != null)
{
m_Plugin = (IPlugin)Activator.CreateInstance(type);
return true;
}
}
return false;
}
public Guid GUID { get { return m_Plugin.GUID; } }
public string Name { get { return m_Plugin.Name; } }
public string Description { get { return m_Plugin.Description; } }
// I debugged and found out the error happens AFTER m_Plugin.Execute
// so the method runs well, but the return back to the pProxy.Execute is throwing the SerializationException
public async Task Execute(PluginPanel panel, string user) { await m_Plugin.Execute(panel, user); }
}
以及加载程序集并获取 SerializationException 的方法:
AppDomainSetup setup = new AppDomainSetup();
// some setup stuff
AppDomain dom = AppDomain.CreateDomain(Guid.NewGuid().ToString(), null, setup);
PluginProxy pProxy = (PluginProxy)dom.CreateInstanceFromAndUnwrap(Assembly.GetExecutingAssembly().CodeBase, typeof(PluginProxy).FullName);
pProxy.Init(app.Apppath);
// I await the task later in code, because the user can cancel the execution
try { tExe = pProxy.Execute(panel, user.Username); }
catch (System.Runtime.Serialization.SerializationException e)
{
// runs always in this catch, even if no Exception from the plugin was thrown
}
catch (Exception e) { AddToErrorLog(panel.PanelName, e); }
finally
{
pProxy.Dispose();
AppDomain.Unload(dom);
}
也许我加载插件的整个概念是错误的?
最佳答案
感谢 Hamlet Hakobyan 和 Stephen Toub 的帖子,我想我能够解决问题。
我替换了来电者的线路
try { tExe = pProxy.Execute(panel, user.Username); }
与
tExe = DoWorkInOtherDomain(pProxy, panel, user.Username);
和 DoWorkInOtherDomain 方法:
private Task DoWorkInOtherDomain(PluginProxy pProxy, PluginPanel panel, string user)
{
var ch = new MarshaledResultSetter<string>();
pProxy.Execute(panel, user, ch);
return ch.Task;
}
最后是代理类:
Task.Run(() =>
{
try
{
m_Plugin.Execute(panel, user).Wait();
}
catch (AggregateException e)
{
if (e.InnerExceptions != null)
foreach (Exception ein in e.InnerExceptions)
AddToErrorLog(panel.PanelName, ein);
}
catch (Exception e) { AddToErrorLog(panel.PanelName, e); }
finally { ch.SetResult(AppDomain.CurrentDomain.FriendlyName); }
});
我需要调用 Wait()
m_Plugin.Execute(panel, user).Wait();
它从插件中捕获异常,所以一切正常。 Wait() 调用应该只阻塞 Task.Run 而不是其他任务。
谁能告诉我这是一个好的解决方案还是我应该改变什么?我不需要结果,所以我只是这样做:
ch.SetResult(AppDomain.CurrentDomain.FriendlyName);
因为没有结果我不知道该怎么做。
关于c# - AppDomain 等待异步任务防止 SerializationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31555702/
下面的简单类继承自 HashSet,因此必须实现 ISerialization 成员(以非标准方式)。当我尝试序列化然后反序列化 Group 的实例时,出现以下异常: Test method Util
我只是创建了最简单的 Singleton EJB 来返回自定义可序列化对象,但是当我调用远程方法时出现以下异常: org.jboss.serial.exception.SerializationExc
我的 web api 项目中有一个 Report 类: [KnownType(typeof(Employee))] [DataContract] public class Report { [
我的程序在加载序列化文件的部分遇到问题。如果文件无法反序列化,我想很好地失败,但由于某种原因,我的程序将中断而不是进入 catch 子句。这是我的代码 using (FileStream fs = n
由于我之前的问题 ( XML serialization of interfaces ) 我得到了另一个问题... 我有一个从数据库导出数据的应用程序。导出过程由实现用于调用的通用接口(interfa
早上好,我有一个 TCP 服务器和一个 TCP 客户端。这是服务器的代码: public static class Server { private static IPEndPoint end
当反序列化带有 EnumMemberAttribute 且值包含空格的标记枚举时,将抛出 SerializationException。值中的空格被视为分隔符。 有没有办法更改分隔符或将值放在引号中?
我创建了在 Selenium 中初始化 Chrome Webdriver 的 NUnit 套件。这适用于 InternetExplorer 驱动程序和 Firefox 驱动程序,但每次我尝试使用 Ch
所以我自己托管 WCF 服务。当我通过客户端调用我的 GetProject() 方法时,我得到一个 Unhandled CommuncationException 和一个 InnerException
我得到一个: System.Runtime.Serialization.SerializationException: Unable to find assembly 'myNameSpace, Ve
我正在编写一个通用过滤器类,主要用于从人群中过滤人员。我正在尝试序列化过滤器类,但在运行时我得到一个 SerializationException: System.Runtime.Serializat
目前我正在使用 LibGDX 的 JSON 输出文件编写类来处理游戏的数据保存(和加载)部分。我一直在谷歌上试图找到解决方案,并且已经接近,但没有雪茄。到目前为止,我已经成功地尝试保存 Array到文
我有以下类(class): import lombok.Data; import java.io.Serializable; @Data public class Person implements
我得到SerializationException经过时ArrayList作为 RPC servlet 方法的参数。类 MyObject仅包含 2 个类型为 String 的字段和Serializab
给定以下代码, [DataContract] public class TestClass { [DataMember] public object _TestVariable; publ
在尝试反序列化一个相对较大的对象图时,我看到了奇怪的行为 ~10000 行,上面有 6 列。我确定问题是在尝试将此数组从服务反序列化回客户端时出现序列化异常。它适用于少于 9000 个对象的数据集,并
我有一个 Windows 服务,它在运行时在另一个 AppDomain 中加载程序集。然后执行它们并最终卸载 AppDomain。问题是插件的执行方法是异步任务,我得到了 SerializationE
我开始尝试 Apache Pivot,因为我想使用 XML 创建 Java GUI。 我关注了他们的Hello BXML tutorial在他们的网站上使用 Maven 项目。 这些是我正在使用的文件
尝试通过 WebApi get 返回列表时出现 SerializationException。 Full error message on pastebin 这是我的代码: HomeControlle
我在 Spring 框架 (4.1.6) 上有应用程序,使用 Spring Security 4.0.1。我在应用程序中使用了@EnableRedisHttpSession 和@EnableSprin
我是一名优秀的程序员,十分优秀!