我有读取各种传感器和处理数据的方法。在这些方法中,我有其他方法通过串口向电路发送命令(以获取传感器值)。通信错误可能会发生,我想知道是否可以“返回”一个异常?例如:
public double AverageSensorValues()
{
try
{
...
double sensor1Value = SensorValue(1);
double sensor2Value = SensorValue(2);
...
}
catch (Exception ex)
{
MessageBox.Show("Error in AverageSensorValues()");
}
}
public double SensorValue(int sensorNum)
{
try {
// Send command to circuit to return value.
string response = SendCommand(commandStringToGetValue);
// Check to see if response is an error
bool isError = ErrorReturned(response);
if(isError)
ProcessError(response); // Throws exception.
... // Other things that could cause exceptions to be thrown.
}
catch (Exception ex)
{
throw new Exception("Error in SensorValue()", ex);
}
}
public void ProcessError(string errorResponse)
{
// Split string and get error parameters (#, input command, etc.)
throw new Exception(String.Format("Error-{0}: See ...", errorNumber)); // Is this OK? More readable than "ER,84,DM,3L" for example.
}这是否还可以,还是被认为是“糟糕的做法”?
谢谢!
编辑
我阅读了不同的回复,看起来我做的完全错误。我试图使用上面的例子作为一个快速的例子,但看起来我应该只是张贴从入门的全部细节。下面是一个关于我的情况的更详细的例子:
public double[] GetHeightAtCoords(CoordClass[] coords) // Get height measurement at various positions. Called after button click, results are displayed on UI.
{
try // Error could occur within one of these methods. If it does, not Program critical but it should notify user and not return any result.
{
for(int coordIndex = 0; coordIndex < coords.Length; coordIndex++) // Cycle through each desired position.
{
...
currentCoords = GetCurrentCoords(); // Get current actuator position.
... //Update UI.
MoveToCoords(coords[coordIndex]); // Move actuator to position.
currentCoords = GetCurrentCoords(); // Verify position.
EngageBrake(); // Lock actuator in place.
double height = GetHeight(); // Read sensor data.
ReleaseBrake(); // Release brake.
...
}
}
catch (Exception ex)
{
// Display in statusbar.
statusBar1.Text = String.Format("Error in GetHeightAtCoords(): {0}", ex.Message);
}
...
return heights; // Return position heights array.
}
public CoordClass GetCurrentCoords() // Method to read positional encoder values.
{
...
try
{
double xPosition = GetXEncoderValue(); // Return x-coord value.
double yPosition = GetYEncoderValue(); // Return y-coord value.
}
catch (Exception ex)
{
throw new Exception("Error in GetCurrentCoords(): {0}", ex.Message);
}
...
return new CoordClass(xPosition, yPosition); // Return current coords.
}
public void MoveToCoords(CoordClass coord) // Method to move actuators to desired positions.
{
try
{
...
currentCoords = GetCurrentCoords(); // See where actuators are now.
... // Setup movement parameters.
MoveToX(coord.X); // Move x-axis actuator to position.
MoveToY(coord.Y); // Move y-axis actuator to position.
}
catch (Exception ex)
{
throw new Exception("Error in MoveToCoords(): {0}", ex.Message);
}
...
}
public double GetXEncoderValue() // Method to return x-coord value.
{
string getXCoordCommand = "SR,ML,01,1"; // Serial command to get x-coord.
...
string controllerResponse = SendReceive(getXCoordCommand); // Send command, get response command.
if(!ResponseOK(controllerResponse)) // If the response doesn't match the "command OK" response (i.e. SR,ML,01,1,OK)...
{
if(IsErrorResponse(controllerResponse)) // See if response is an error response (e.g. command error, status error, parameter count error, etc.)
// Some known error type occurred, cannot continue. Format error string (e.g. ER,SRML,61) to something more meaningful and report to user (e.g. Read X Value Error: Status error.).
throw new Exception("Read X Value Error-{0}: {1}", errorNumber, (ErrorEnum)errorNumber);
else
// Something else went wrong, cannot continue. Report generic error (Read X Value Error.).
throw new Exception("Read X Value Error.");
}
...
}
// GetYEncoderValue(), MoveToX(), MoveToY(), GetHeight(), EngageBrake() and ReleaseBrake() follow the same format as EngageBrake().这是我的逻辑如果..。
调用顺序: GetHeightAtCoords() -> MoveToCoords() -> GetCurrentCoords() -> GetXEncoderValue(),具有控制器响应的错误。
在GetXEncoder()中抛出新异常、在GetCurrentCoords()中捕获和重新抛出新异常、在MoveToCoords()中捕获和重新抛出新异常、在GetHeightAtCoords()中捕获并在状态栏中显示消息(message = "Error in GetHeightAtCoords():Error in MoveToCoords():Error in GetCurrentCoords():Read X Value Error-6: status Error")。
由于GetXEncoder()可以从方法中的多个位置调用,所以我认为,如果让原始的异常气泡一直向上,对用户没有多大帮助。“GetHeightAtCoords()中的错误:读取X值错误-6:状态错误”,哪一次?)。以这个例子为例,哪个读取X值失败?GetHeightAtCoords() -> MoveToCoords() -> GetCurrentCoords() -> GetXEncoderValue()或GetHeightAtCoords() -> GetCurrentCoords() -> GetXEncoderValue()?
希望这一点更清楚:
这样的事做过吗?你建议我怎么做?再次感谢大家的意见!
发布于 2011-10-10 22:48:33
创建一个总是抛出异常的方法有点难闻。看起来,这会处理错误,然后继续。我宁愿这样做:
if(isError)
throw MakeMeAnException(response);
...
}
public Exception MakeMeAnException(string errorResponse)
{
// Split string and get error parameters (#, input command, etc.)
return new MyException(String.Format("Error-{0}: See ...", errorNumber));
}这非常清楚地表明,if (isError)结果总是抛出;在您的原始版本中,很难看出它会这样做。
另外,异常的堆栈跟踪是在抛出的点设置的,因此这会将堆栈跟踪设置为检测错误的点,而不是构造异常的点,这似乎更好。
在您的代码中还有更多的错误实践。
new Exception;定义自己的异常类并抛出它。这样,调用方就可以捕获您的异常specifically.发布于 2011-10-10 22:11:22
这是不好的,因为您隐藏了异常的类型:
catch (Exception ex)
{
throw new Exception("Error in SensorValue()", ex);
}最好是简单地省略try { ... } catch { ... }。只有捕获异常,您可以做一些有用的事情。
这很糟糕,因为您正在捕获所有内容,但没有显示实际错误是什么:
catch (Exception ex)
{
MessageBox.Show("Error in AverageSensorValues()");
}您可能已经捕获了一个OutOfMemoryException、一个NullReferenceException或其他什么东西。你的用户不会知道。至少显示异常消息。
throw new Exception(String.Format("Error-{0}: See ...", errorNumber));这是对异常的合理使用--将错误代码更改为异常。但是,您可能应该使用比Exception更具体的类型--甚至可能是从Exception派生的自定义类。
发布于 2011-10-10 22:15:54
没有必要使用这样的异常,异常应该是发生意外事件时的异常。它们不应成为一般控制流程的一部分。
https://stackoverflow.com/questions/7719241
复制相似问题