1

次の KB 記事の例に従って、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, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' またはその依存関係の 1 つを読み込めませんでした。一般的な例外 (HRESULT からの例外: 0x80131500)

エラーのアセンブリは、AssemblyLoader が検索するフォルダーの 1 つにあります。手順をもう一度実行すると、成功します。

2 つのコンソール アプリでこのアセンブリ ローダーを使用し、同じ dll に同時にアクセスして、dll がロックされているかどうかを確認しようとしましたが、これは問題ではないようです。

また、これはバッチの 1 つからの単なるログであることにも言及する必要があります。他にもありますが、同じアセンブリがロードされていないことはめったにありません。

次にどこから解決策を探し始めればよいかわかりません。

4

1 に答える 1

0

これは、各バッチが実行される前に dll を更新する更新スクリプトが原因でした。2 つのバッチが同時に実行されていて、更新が必要な dll がある場合、問題の原因となっている dll でロックが発生していました。

このスクリプトを削除してから 1 週間が経過しましたが、まだ問題は発生していません。したがって、これが問題であるというのが私たちの結論です。

于 2013-05-21T07:34:21.713 に答える