C# AccessViolationException-是静态方法导致的吗?
我创建了一个静态方法,其目的是加载DLL,并使用反射返回其中包含的类的实例 为了让您保持正确的心态,请提供以下事实:C# AccessViolationException-是静态方法导致的吗?,c#,.net,winforms,reflection,access-violation,C#,.net,Winforms,Reflection,Access Violation,我创建了一个静态方法,其目的是加载DLL,并使用反射返回其中包含的类的实例 为了让您保持正确的心态,请提供以下事实: 由于属于所返回类的对象实例(基类中的ListLabel公共成员),间接加载的第三方DLL中出现异常 我担心的是,这可能是我的方法造成的故障,而不是第三方组件的故障。在我将其提交给供应商之前,我想先尝试消除这种可能性 以下是发生异常的方法: namespace MyNamespace { public abstract class baseClass {
ListLabel
公共成员),间接加载的第三方DLL中出现异常namespace MyNamespace
{
public abstract class baseClass
{
public ListLabel LL = new ListLabel(); //this is where the exception actually originates
public baseClass()
{
LL.DrawPage += new DrawPageHandler(LL_DrawPage);
LL.EnableCallbacks = true;
LL.AddVarsToFields = true;
LL.DelayTableHeader = true;
LL.IncrementalPreview = true;
}
public static baseClass GetClassInstance(String DLLName)
{
try
{
if (!String.IsNullOrEmpty(DLLName))
{
String fileName = DLLName.EndsWith(".dll") ? DLLName : DLLName + ".dll";
Assembly theDLL = Assembly.LoadFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), fileName));
foreach (Type t in theDLL.GetTypes())
{
if (typeof(baseClass).IsAssignableFrom(t))
return (baseClass)Activator.CreateInstance(t); //this line instantiates the baseClass instance, and causes the new LL object to be created, firing the exception
}
}
}
catch (Exception ex)
{
if (ex is ReflectionTypeLoadException)
{
Exception[] exa = ((ReflectionTypeLoadException)ex).LoaderExceptions;
for (Int32 i = 0; i < exa.Length; i++)
ErrorHandler.WriteError(String.Format("ReflectionTypeLoadException occurred while loading DLL '{0}' (ex #{1}):\n {2}", DLLName, i, exa[i].ToString()));
}
else
{
ErrorHandler.WriteError(String.Format("Error loading DLL: {0}", DLLName));
}
}
return null;
}
}
}
名称空间MyNamespace
{
公共抽象类基类
{
public ListLabel LL=new ListLabel();//这是异常实际发生的地方
公共基类()
{
LL.DrawPage+=新的DrawPageHandler(LL_DrawPage);
LL.EnableCallbacks=true;
LL.AddVarsToFields=true;
LL.DelayTableHeader=true;
LL.IncrementalPreview=true;
}
公共静态基类GetClassInstance(字符串DLLName)
{
尝试
{
如果(!String.IsNullOrEmpty(DLLName))
{
字符串文件名=DLLName.EndsWith(“.dll”)?DLLName:DLLName+“.dll”;
Assembly thedell=Assembly.LoadFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),fileName));
foreach(在dell.GetTypes()中键入t)
{
if(typeof(baseClass).IsAssignableFrom(t))
return(baseClass)Activator.CreateInstance(t);//此行实例化基类实例,并导致创建新的LL对象,引发异常
}
}
}
捕获(例外情况除外)
{
如果(ex是ReflectionTypeLoadException)
{
异常[]exa=((ReflectionTypeLoadException)ex).LoaderExceptions;
对于(Int32 i=0;i
请注意,基类
是静态方法的提供者,它是抽象
,并且是由GetClassInstance()返回的类型
我偶尔会遇到一组异常,其核心是AccessViolationException
。我收到的堆栈跟踪如下所示:
在combit.ListLabel18.NativeMethods.LlSetDebug32(Int32非关闭)
位于combit.ListLabel18.LlCore.LlSetDebug(LlDebug onOff)
combit.ListLabel18.ListLabel.set_Debug(LlDebug值)为
combit.ListLabel18.ListLabel.Init(LlLanguage,CultureInfo
区域性、布尔启用回调、字符串debugLogFilePath)位于
combit.ListLabel18.ListLabel..ctor()位于AllMax.baseReport..ctor()
在AllMaxReport.rpt3320DMR..ctor()处
System.RuntimeType.CreateInstanceImpl(Boolean publicOnly,Boolean
skipVisibilityChecks,布尔填充缓存)
这在任何方面都是不一致的,这也是我担心这是我的错的主要原因。这可能与以下因素的结合有关:
重复动态加载DLL(这通常发生在对GetClassInstance()
的多次调用之间循环时)
使用静态
方法
将反射
放入该静态
方法中
创建提供静态
方法的同一类的实例
看看堆栈跟踪,如果在发布模式下运行,行为会有什么不同吗?@ledbutter考虑到跟踪中的明显调用,我的工作假设不会有什么不同。但我也没有花太多时间在那种模式下运行,所以我真的不能说。由于它是间歇性的,所以很难有任何信心。刚刚偶然发现,这篇文章的最佳实践是使用ListLabel的保护实例,以避免DLL的卸载和加载。只需在启动时创建一个ListLabel对象,并在应用程序即将关闭时处理它。这将提高性能并消除访问冲突。