简体   繁体   English

.net有条件不正确评估

[英].net conditional not evaluating properly

I have the following simple block of code 我有以下简单的代码块

  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));

Since the assembly referenced by assmSpec does in fact exist (The File.Exists() evals to true), I expect that the exception would not be thrown. 由于assmSpec引用的程序集确实存在( File.Exists() evals为true),我希望不会抛出异常。 But it is. 但它是。 the code steps into the throw statement. 代码步入throw语句。 To debug, I modified the code to read: 为了调试,我将代码修改为:

  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));

Here, asmExists evals to true, and The code still steps into the throw. 在这里, asmExists篡改为真,并且代码仍然进入抛出。

I then modified the code to read: 然后我将代码修改为:

  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));

and again, the code still hits the throw. 再一次,代码仍然命中。 Something is clearly very wrong here. 这里显然是非常错误的。 Has anyone have an explanation ? 有人有解释吗? Am I doing something really obviously stupid here? 我在这里做的事真的很愚蠢吗?

fwiw, this code is in a method that also has a try - catch - finally construction, but it is before all of them (before the try) ... fwiw,这个代码在一个方法中也有一个try - catch - finally构造,但它在所有这些之前(在try之前)......


The full method is: 完整的方法是:

  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;
        }
    }

Check that there is no text (code or semicolon) following the if () statement on the same line. 检查同一行上的if ()语句后面是否没有文本(代码或分号)。 The most likely cause is that the "throw" is not actually "inside" the if statement, so it's always executed. 最可能的原因是“throw”实际上并不是if语句的“内部”,所以它总是被执行。

Check that you are debugging a DEBUG build - you may get odd values reported in the debugger for a RELEASE build, which may make it look as though a variable is true when in fact it is false. 检查您是否正在调试DEBUG构建 - 您可能会在调试器中为RELEASE构建报告奇数值,这可能使得它看起来好像变量为true,而实际上它是false。

It's also possible under some circumstances (though only usually with things like references to precompiled dlls or corrupt pdb files) to be looking at different code than you are debugging, giving the impression that changes you are making to the source are being ignored. 在某些情况下(尽管通常仅对引用预编译的dll或损坏的pdb文件这样的内容)查看不同于调试的代码也是可能的,这给人的印象是你正在忽略对源进行的更改。 Do a Build > Clean, check that the assembly you're running is no longer present on disk, and then rebuild it to be sure that it's up to date and in sync with your source code. 执行Build> Clean,检查磁盘上是否已不再存在正在运行的程序集,然后重新构建它以确保它是最新的并与源代码同步。

I've just tried something similar, and it works fine for me. 我刚尝试了类似的东西,它对我来说很好。 Have you tried this using a statement block instead of a single throw line? 你是否尝试使用语句块而不是单个抛出线?

The compiler could be confused, and may need to be restarted. 编译器可能会混淆,可能需要重新启动。 It's not unheard of. 这不是闻所未闻的。 :/ :/

If you look at the internals of the File.Exists method, you find that it will return false under numerous circumstances including: 如果你看一下File.Exists方法的内部,你会发现它会在很多情况下返回false,包括:

  1. path is null or an empty string path为null或空字符串
  2. The file does not exist 该文件不存在
  3. The OS thinks the file is actually a directory 操作系统认为该文件实际上是一个目录
  4. The account trying to access the file does not have read permissions. 尝试访问该文件的帐户没有读取权限。
  5. Some other internal NotSupportedException, SecurityException, IOException or UnauthorizedAccessException is thrown. 抛出了一些其他内部NotSupportedException,SecurityException,IOException或UnauthorizedAccessException。

The problem is that all those potential errors are buried. 问题是所有这些潜在的错误都被埋没了。 I'd suggest trying the FileInfo class instead: 我建议尝试使用FileInfo类:

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

The constructor on FileInfo will throw one of a handful of exceptions back to you which might give you more information about the issue. FileInfo上的构造函数会向您返回一些异常中的一个,这可能会为您提供有关该问题的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM