PDA

View Full Version : Catching Warnings



ed
03-20-2008, 11:32 AM
In the IMSL C# and JMSL products, we use the platform Exception handling to deal with serious errors. However, Warning messages are printed to the standard error output console (System.err in Java and System.Console.Error in .NET). For console applications, this is often OK, but for applications where you need all information to arrive via a graphical user interface, you will want a better way to get the warning message to the user.

We have provided the ability to extend our base classes for this method using the WarningObject class. The most common use of this class is actually to set it to null to quiet all warnings. But when you want to report warnings somewhere other than the console, this is the class you want to extend.

The following example is in C#, but would be very similar in Java. The Main() method makes a call to the DenseLP optimization class with a poorly structured problem so that a warning about the constraints is issued. We use a try/catch block in case any other exceptions are thrown, but that will not be kicked off for the expected warning.

The key thing is to extend the Imsl.WarningObject (http://www.vni.com/products/imsl/cSharp/v50/manual/api/Imsl.WarningObject.html) class, here called MyWarningObject. We then override the Print() method to pop up a MessageBox instead of writing to the console. The arguments to the method are a little cryptic and are used internally to reference embedded resources in the IMSL C# assembly. (JMSL and Java uses a very similar technique with ResourceBundle). Knowing this isn't obvious, the example below shows how to find the proper resource bundle and use the supplied key to return the appropriate message. All of this is put together in a straightforward call to MessageBox.Show().

Recognize that this is not going to be the best method in all cases. The standard WarningObject includes a lock() call for thread safety. Additionally, the MessageBox is a blocking dialog that may not be the right choice.

To show that execution continues after the warning has been issued we then pop up another message containing the objective value for the optimization problem.


using System;
using Imsl.Math;

namespace ExceptionDiag
{
class Program
{
static void Main(string[] args)
{
int[] irtype = new int[] { 1, 2 };
double[] a = new double[] { 1.5, 0.5 };
double[] b = new double[] { -1.0, -3.0 };
double[] xub = new double[] { 1.0e30, 1e30 };
double[] xlb = new double[] { 2, 2 };
double[,] na = { { 1.0, 1.0 }, { 1.0, 1.0 } };

try
{
// Override the WarningObject and define your own behavior
Imsl.Warning.WarningObject = new MyWarningObject();
Program p = new Program();
DenseLP zf = new DenseLP(na, a, b);
zf.SetUpperBound(xub);
zf.SetLowerBound(xlb);
zf.SetConstraintType(irtype);
zf.Solve();
System.Windows.Forms.MessageBox.Show("Objective Value = " +
zf.ObjectiveValue.ToString(), "Objective Value");
}
catch (Imsl.IMSLException exception)
{
System.Windows.Forms.MessageBox.Show(exception.Mes sage);
}
}
}

/// <summary>
/// A new WarningObject to implement user-defined behavior for IMSL Warnings
/// </summary>
class MyWarningObject : Imsl.WarningObject
{
/// <summary>
/// Override the Print method with this argument list. Using the input
/// parameters you can query the details of the error message from
/// resources embedded in the IMSL C# Library assembly.
/// </summary>
/// <param name="source"></param>
/// <param name="baseName"></param>
/// <param name="key"></param>
/// <param name="arg"></param>
public override void Print(object source, string baseName, string key, object[] arg)
{
System.Resources.ResourceManager rm = new System.Resources.ResourceManager(
baseName + ".ErrorMessages", source.GetType().Assembly);
string msg = rm.GetString(key);
System.Windows.Forms.MessageBox.Show(msg,
source.GetType().FullName + " Warning",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Warning);
}
}
}