.net条件不能正确计算



我有以下简单的代码块

  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()的值为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));

这里,asmExists的值为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));

,代码仍然会抛出。这里显然出了很大的问题。有人能解释一下吗?我做了什么明显很蠢的事吗?

现在,这段代码是在一个方法中,它也有一个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;
        }
    }

检查同一行if ()语句后是否有文本(代码或分号)。最有可能的原因是"throw"实际上并不在if语句内,所以它总是被执行。

检查你正在调试一个DEBUG版本——你可能会在RELEASE版本的调试器中得到奇怪的报告值,这可能会使它看起来好像一个变量是真的,而实际上它是假的。

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

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

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

如果您查看文件的内部。方法,您会发现在许多情况下它将返回false,包括:

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

问题是所有这些潜在的错误都被隐藏了。我建议尝试FileInfo类代替:

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

FileInfo的构造函数会抛出一个异常给你,这可能会给你更多关于这个问题的信息。

相关内容

  • 没有找到相关文章

最新更新