2013-04-26 48 views
0

失败之后,我们以点带面的.N​​et正确的文件夹装入从组件实现的AssemblyResolve事件以下知识库文章的例子:http://support.microsoft.com/kb/837908装载程序集随机

这是我们的当前实现:

public static class AssemblyLoader 
{ 
    /// <summary> 
    /// A custom AssemblyResolver that will search for missing assemblies in the root and subfolders of the executing assembly 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="args"></param> 
    /// <returns></returns> 
    public static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
    { 
     string assemblyPath = string.Empty; 
     string assemblyFileName = string.Empty; 

     try 
     { 
      // This handler is called only when the common language runtime tries to bind to the assembly and fails. 
      string rootProbingPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); 


      // Loop through the referenced assembly names. 
      assemblyFileName = args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll"; 

      // Search for the filename in the root and subfolders of the rootProbingPath 
      string[] matchingAssemblies = Directory.GetFiles(rootProbingPath, assemblyFileName, SearchOption.AllDirectories); 

      // If a match is found, awesomeness was achieved! 
      if (matchingAssemblies.Length > 0) 
       assemblyPath = matchingAssemblies[0]; 

      // Throw a clear exception when the assembly could not be found. 
      if (string.IsNullOrEmpty(assemblyPath)) 
       throw new FileNotFoundException(string.Format("AssemblyLoader: Could not find assembly '{0}' in '{1}' or its subfolders.", assemblyFileName, rootProbingPath)); 

      Console.WriteLine(string.Format("[" + DateTime.Now.ToString() + "] AssemblyLoader: Assembly '{0}' found at '{1}'", assemblyFileName, assemblyPath)); 

      // Load the assembly from the specified path. 
      return Assembly.LoadFrom(assemblyPath, AppDomain.CurrentDomain.Evidence); 
     } 
     catch (Exception ex) 
     { 
      throw new Exception(string.Format("[" + DateTime.Now.ToString() + "] The assemblyloader could not load the assembly '{0}' from path '{1}': " + ex.Message, assemblyFileName, assemblyPath), ex); 
     } 
    } 
} 

我们在所有的往往并行运行,并且大多采用相同的组件就是批程序使用。

定期间歇会崩溃离开下列线索:

[26/04/2013 12时35分01秒] AssemblyLoader:装配 'COMPANY.DistributieOrderFacade.dll' 在 “C发现:\ COMPANY_Batch \ MDS \可执行\ MDS \ FACADE \ COMPANY.DistributieOrderFacade.dll '

[26/04/2013 12时35分01秒] AssemblyLoader:装配 'COMPANY.DOCUMENTCENTERDOCS.dll' 在 发现' C:\ COMPANY_Batch \ MDS \ Executables \ MDS \ CLIENT \ COMPANY.DOCUMENTCENTERDOCS.dll'

26/04/2013 12时35分01秒:在 队列创建COMPANYDocument ...:\ rug.adroot \ dfsroot \ MDS \ DATA \ queue_new \ 26/04/2013 12时35分01秒

无法加载文件或程序集'COMPANY.DistributieOrderBRDA, 版本= 1.0.0.0,Culture = neutral,PublicKeyToken = null'或其依赖关系之一 。一般例外(来自HRESULT的例外:0x80131500)

错误中的程序集确实位于AssemblyLoader搜索的其中一个文件夹中。如果我再次运行该程序,它会成功。

我试着看看在两个控制台应用程序中使用这个程序集加载器,并且同时访问相同的DLL,但是这似乎没有问题。

我还应该提到,这只是来自其中一个批次的日志。还有其他的,它很少是没有被加载的相同的程序集。

我不知道从哪里开始寻找解决方案。

回答

0

这是由于更新脚本在每批运行之前更新了dll的。当两个批处理同时运行,并且有一个需要更新的dll时,dll的锁正在导致问题。

我们已经删除了这个脚本一个星期了,并且还没有看到任何问题。所以我们的结论是,这是问题所在。