按照以下知识库文章的示例,我们已经实现了AssemblyResolve事件,以便将.Net指向正确的文件夹以从以下位置加载程序集: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:Assembly 找到'COMPANY.DistributieOrderFacade.dll' 'C:\ COMPANY_Batch \ MDS \可执行\ MDS \ FACADE \ COMPANY.DistributieOrderFacade.dll'
[26/04/2013 12:35:01] AssemblyLoader:Assembly 找到'COMPANY.DOCUMENTCENTERDOCS.dll' 'C:\ COMPANY_Batch \ MDS \可执行\ MDS \ CLIENT \ COMPANY.DOCUMENTCENTERDOCS.dll'
26/04/2013 12:35:01:创建COMPANYDocument ... in queue:\ rug.adroot \ dfsroot \ mds \ Data \ queue_new \ 26/04/2013 12:35:01
无法加载文件或程序集'COMPANY.DistributieOrderBRDA, Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'或其中一个 依赖。一般异常(HRESULT异常:0x80131500)
错误中的程序集确实位于AssemblyLoader搜索的其中一个文件夹中。如果我再次运行该程序,它确实会成功。
我试图通过在两个控制台应用程序中使用这个程序集加载器来锁定dll,并同时访问相同的dll,但这似乎不是问题。
我还应该提到,这只是其中一个批次的日志。还有其他一些,并且很少有相同的组件没有被加载。
我不知道从哪里开始寻找解决方案。
答案 0 :(得分:0)
这是由于更新脚本在每个批处理运行之前更新了dll。当两个批次同时运行并且有一个需要更新的dll时,在dll上发生了锁定,这导致了问题。
我们已经删除了这个脚本一个星期了,还没有看到任何问题。所以我们的结论是这就是问题所在。