0

次の単純なコードブロックがあります

  var assmSpec = util.ASSEMBLYFOLDER + task.AssemblyName; // evals to valid fileSpec
  if (!File.Exists(assmSpec))
      throw new TaskException(string.Format(
          "Assembly [{0}] cannot be located.", assmSpec));

assmSpec によって参照されるアセンブリが実際に存在するため ( File.Exists()evals が true になる)、例外がスローされないことが予想されます。しかし、そうです。コードは throw ステートメントにステップ インします。デバッグするために、コードを次のように変更しました。

  var assmSpec = util.ASSEMBLYFOLDER + task.AssemblyName; // evals to valid fileSpec
  var asmExists = File.Exists(assmSpec);
  if (!asmExists)
      throw new TaskException(string.Format(
          "Assembly [{0}] cannot be located.", assmSpec));

ここで、asmExistsevals が true になり、コードはまだスローに入ります。

次に、コードを次のように変更しました。

  var assmSpec = util.ASSEMBLYFOLDER + task.AssemblyName; // evals to valid fileSpec
  if (!File.Exists(assmSpec) && File.Exists(assmSpec))
      throw new TaskException(string.Format(
         "Assembly [{0}] cannot be located.", assmSpec));

繰り返しますが、コードはまだスローにヒットします。ここで何かが明らかに非常に間違っています。誰か説明がありますか?私はここで本当に明らかに愚かなことをしていますか?

fwiw、このコードは、try - catch - finally 構造も持つメソッドにありますが、それらすべての前 (try の前) にあります...


完全な方法は次のとおりです。

  public void StartProcess(Task task)
    {
        log.Write(log.Level.Debug, string.Format(
            "TaskWorker.StartProcess {0} process",
            task.Name), task.Name);
        WorkerMessageManager.MsgArrvdWorkerHndlr += MsgArrvdWorkerHndlr;
        var tskName = task.Name;
        var assmSpec = util.ASSEMBLYFOLDER + task.AssemblyName;
        if (!File.Exists(assmSpec))
            throw new TaskException(string.Format(
                "Assembly [{0}] cannot be located.", assmSpec));

        try
        {
            WorkerMessageManager.NotifyWorker(new ProgressTaskMessage(
                                    tskName, "", tskName + "  starting..."));
            // -------------------------------------------
            Assembly dA;
            try { dA = Assembly.LoadFrom(assmSpec); }
            catch(FileNotFoundException nfX)
            { throw new TaskException(string.Format(
                "Assembly [{0}] cannot be located.", assmSpec), 
                nfX); }
            // -------------------------------------------
            var iTsk = (IExecuteTasks)dA.CreateInstance(task.ClassName);
            if (iTsk == null)
                throw new TaskException(
                    string.Format("Unable to instantiate {0} from {1}",
                        task.ClassName, task.AssemblyName));

            if (iTsk.TaskName != tskName) // do not execute if names do not match
                throw new TaskNameMismatchException(string.Format(
                    "CHECK CONFIGURATION SETTINGS,  Data Task Name Mismatch.{0}" +
                    "Task name defined in TaskScheduler.config [{1}], {0} does " +
                    "not match name [{2}] as defined in Task Logic assembly: {3}.{4}",
                        sNL, tskName, iTsk.TaskName, task.AssemblyName, 
                        task.ClassName),  tskName, iTsk.TaskName);
            // -------------------------------------------
            iTsk.DataImportProgressEvent += OnProgressReport;
            iTsk.ProcessCompletedEvent += OnProcessCompleted;
            iTsk.GeneralEvent += OnGeneralEvent;
            // -----------------------------------
            log.Write(log.Level.Debug, string.Format(
                  "{0} process Started", task.Name),
                  task.Name);
            if (task.JobQueue.HasJobReady)
                iTsk.StartTask(JobQueues.Instance.DeQueue(tskName));
            else iTsk.StartTask(); 
            log.Write(log.Level.Debug, string.Format(
                  "{0} process Completed", task.Name),
                  task.Name);
        }
        catch (TaskNameMismatchException inmX)
        { log.Write(log.Level.Warn, inmX.Message, tskName, inmX); }

        catch (BpaTaskException mX)
        {
            var errMsg = string.Format(
                "Error in Data Import StartProcess(). " + sNL +
                "Exception {0}: {1}, " + sNL +
                "Stack Trace: {2}",
                mX, mX.Message, mX.StackTrace); 
            log.Write(log.Level.Error, errMsg, 
                        task.Name, mX);
        }

        catch(Exception X)
        {
            var errMsg = string.Format(
                "Error in Data Import StartProcess(). " + sNL +
                "Exception {0}: {1}, " + sNL +
                "Stack Trace: {2}",
                X, X.Message, X.StackTrace);
            log.Write(log.Level.Error, errMsg, task.Name, X);

            // WorkerMessageManager.NotifyWorker(new ImportFailMessage(X));
            // This throw instruction causes the Scheduler service to stop alltogether
            // I'm Removing the throw for now, because it seems inappropriate to 
            //          kill the whole service..
            throw;
        }

        finally
        {
            task.IsRunning = false;
            WorkerMessageManager.MsgArrvdWorkerHndlr -= MsgArrvdWorkerHndlr;
        }
    }
4

3 に答える 3

2

if ()同じ行のステートメントの後にテキスト (コードまたはセミコロン) がないことを確認してください。最も可能性の高い原因は、「スロー」が実際には if ステートメントの「内部」にないため、常に実行されることです。

DEBUG ビルドをデバッグしていることを確認してください。RELEASE ビルドのデバッガーで奇妙な値が報告されることがあります。これにより、変数が実際には false であるのに、true であるかのように見える場合があります。

状況によっては (通常はプリコンパイル済み dll への参照や破損した pdb ファイルの場合のみ)、デバッグしているコードとは異なるコードが表示され、ソースに加えた変更が無視されているような印象を受けることもあります。[ビルド] > [クリーン] を実行し、実行中のアセンブリがディスク上に存在しないことを確認してから、アセンブリを再構築して、最新の状態でソース コードと同期していることを確認します。

于 2011-04-12T22:33:01.080 に答える
0

私はちょうど似たようなことを試しましたが、それは私にとってはうまくいきます。単一のスロー行の代わりにステートメント ブロックを使用してこれを試しましたか?

コンパイラが混乱する可能性があり、再起動が必要になる場合があります。前代未聞ではありません。:/

于 2011-04-12T22:25:37.043 に答える
0

File.Exists メソッドの内部を見ると、次のようなさまざまな状況で false が返されることがわかります。

  1. パスが null または空の文字列です
  2. ファイルが存在しません
  3. OSは、ファイルが実際にはディレクトリであると認識しています
  4. ファイルにアクセスしようとしているアカウントには読み取り権限がありません。
  5. その他の内部 NotSupportedException、SecurityException、IOException、または UnauthorizedAccessException がスローされます。

問題は、これらの潜在的なエラーがすべて埋もれていることです。FileInfo代わりにクラスを試すことをお勧めします:

var fileInfo = new FileInfo( assmSpec );
if ( !fileInfo.Exists )
    throw new TaskException( ...

FileInfo のコンストラクターは、いくつかの例外の 1 つを返します。これにより、問題に関する詳細情報が得られる場合があります。

于 2011-05-09T20:39:25.170 に答える