我有以下简单的代码块
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));
在这里,asmExists
逐渐变为真,而且代码仍然进入了抛出。
然后我将代码修改为:
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构造,但它在所有这些之前(在尝试之前)......
完整的方法是:
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;
}
}
答案 0 :(得分:2)
检查同一行上的if ()
语句后面是否有文本(代码或分号)。最可能的原因是“throw”实际上并不是if语句的“内部”,所以它总是被执行。
检查您是否正在调试DEBUG构建 - 您可能会在调试器中为RELEASE构建报告奇数值,这可能使得它看起来好像变量为true,而实际上它是假的。
在某些情况下(尽管通常仅提供对预编译dll或损坏的pdb文件的引用)也可以查看与调试不同的代码,从而给人的印象是,您对源代码所做的更改将被忽略。做一个Build>清理,检查您正在运行的程序集是否已不再存在于磁盘上,然后重新构建它以确保它是最新的并与源代码同步。
答案 1 :(得分:0)
我刚试过类似的东西,它对我来说很好。您是否尝试使用语句块而不是单个抛出线?
编译器可能会混淆,可能需要重新启动。这不是闻所未闻的。 :/
答案 2 :(得分:0)
如果你看一下File.Exists方法的内部,你会发现它会在很多情况下返回false,包括:
问题是所有这些潜在的错误都被埋没了。我建议改为尝试FileInfo
课程:
var fileInfo = new FileInfo( assmSpec );
if ( !fileInfo.Exists )
throw new TaskException( ...
FileInfo上的构造函数会向您返回一些异常中的一个,这可能会为您提供有关该问题的更多信息。