.net условно не оценивается должным образом - PullRequest
0 голосов
/ 13 апреля 2011

У меня есть следующий простой блок кода

  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, и код все еще входит в ход.

Затем я изменил код для чтения:

  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, но это перед всеми ними (перед попыткой) ...


полный метод:

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

Ответы [ 3 ]

2 голосов
/ 13 апреля 2011

Убедитесь, что в той же строке после оператора if () нет текста (кода или точки с запятой).Наиболее вероятная причина заключается в том, что «throw» на самом деле не «внутри» оператора if, поэтому он всегда выполняется.

Проверьте, что вы отлаживаете сборку DEBUG - вы можете получить нечетные значения, указанные в отладчике длясборка RELEASE, которая может заставить ее выглядеть так, как будто переменная истинна, хотя на самом деле она ложна.

Это также возможно при некоторых обстоятельствах (хотя только обычно с такими вещами, как ссылки на предварительно скомпилированные dll или поврежденные файлы pdb)смотреть на код, отличный от отладочного, создавая впечатление, что изменения, которые вы вносите в исходный код, игнорируются.Выполните команду «Сборка»> «Очистить», убедитесь, что используемая сборка больше не присутствует на диске, а затем пересоберите ее, чтобы убедиться, что она обновлена ​​и синхронизирована с вашим исходным кодом.

0 голосов
/ 10 мая 2011

Если вы посмотрите на внутреннюю часть метода File.Exists, вы обнаружите, что он вернет false при многочисленных обстоятельствах, включая:

  1. путь нулевой или пустая строка
  2. Файл не существует
  3. ОС считает, что файл на самом деле является каталогом
  4. У учетной записи, пытающейся получить доступ к файлу, нет прав на чтение.
  5. Выдается другое внутреннее исключение NotSupportedException, SecurityException, IOException или UnauthorizedAccessException.

Проблема в том, что все эти потенциальные ошибки похоронены. Вместо этого я бы предложил попробовать класс FileInfo:

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

Конструктор FileInfo выдаст вам несколько исключений, которые могут дать вам больше информации о проблеме.

0 голосов
/ 13 апреля 2011

Я только что попробовал что-то похожее, и оно прекрасно работает для меня. Вы пробовали использовать блок операторов вместо одной строки броска?

Компилятор может быть сбит с толку, и может потребоваться перезапуск. Это не неслыханно. : /

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...