Динамическая загрузка сборок с использованием события AssemblyResolve завершается случайным образом

Следуя примеру следующей статьи базы знаний, мы реализовали событие 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: сборка "COMPANY.DistributieOrderFacade.dll" найдена в "C:\COMPANY_Batch\MDS\Executables\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, культура = нейтральная, PublicKeyToken=null' или одна из ее зависимостей. Общее исключение (исключение из HRESULT: 0x80131500)

Сборка в ошибке действительно находится в одной из папок, которые ищет AssemblyLoader. И если я снова запустил процедуру, она прошла успешно.

Я пытался увидеть, не блокируются ли библиотеки DLL с помощью этого загрузчика сборок в двух консольных приложениях и одновременно получают доступ к одним и тем же библиотекам DLL, но это, похоже, не является проблемой.

Я должен также упомянуть, что это просто журнал одной из партий. Есть и другие, и это редко та же сборка, которая не загружается.

Я не знаю, где начать искать решение дальше.

1 ответ

Решение

Это было связано с обновлением скрипта, который обновлял dll перед запуском каждого пакета. Когда две партии работали одновременно и была dll, которая нуждалась в обновлении, на dll возникали блокировки, которые вызывали проблему.

Мы удалили этот скрипт на неделю и пока не видели никаких проблем. Итак, мы пришли к выводу, что это была проблема.

Другие вопросы по тегам