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()评估为真),我希望不会引发异常。但它是。代码进入 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,并且代码仍然进入 throw。

然后我将代码修改为:

  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 构建的奇怪值,这可能会使变量看起来好像是 true,而实际上它是 false。

在某些情况下(尽管通常只有对预编译的 dll 或损坏的 pdb 文件的引用)也有可能查看与您正在调试的代码不同的代码,给人的印象是您对源代码所做的更改被忽略了。执行 Build > Clean,检查您正在运行的程序集是否不再存在于磁盘上,然后重新构建它以确保它是最新的并与您的源代码同步。

于 2011-04-12T22:33:01.080 回答
0

我刚刚尝试过类似的东西,对我来说效果很好。您是否尝试过使用语句块而不是单个 throw 行?

编译器可能会混淆,可能需要重新启动。这并非闻所未闻。:/

于 2011-04-12T22:25:37.043 回答
0

如果您查看 File.Exists 方法的内部结构,您会发现它会在多种情况下返回 false,包括:

  1. 路径为 null 或空字符串
  2. 文件不存在
  3. 操作系统认为该文件实际上是一个目录
  4. 尝试访问该文件的帐户没有读取权限。
  5. 引发其他一些内部 NotSupportedException、SecurityException、IOException 或 UnauthorizedAccessException。

问题是所有这些潜在的错误都被掩埋了。我建议FileInfo改为尝试上课:

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

FileInfo 上的构造函数将向您抛出少数异常之一,这可能会为您提供有关该问题的更多信息。

于 2011-05-09T20:39:25.170 回答