Terminate Optimization from C# library through user input - CTRL-C
AnsweredHi,
I am currently developing a C# .NET class library (.dll) which is referenced from within another software (CAD software). With this library I am calling Gurobi through its C# API.
I can easily build a model, run the optimization, and extract results. However, for convenience, I would like to implement the possibility to interrupt / terminate the optimization when pressing a combination on the keyboard, e.g. CTRL-C.
I know CTRL-C terminates the Gurobi optimization in a console application but it seems more difficult in a standalone .dll that is not running in a console. In this case, it seems that CTRL-C is not forwarded to Gurobi.
My question is, how can I set up Gurobi in C# such that it reacts to CTRL-C (or any other key combination, I don't actually care) and terminates the optimization. This should possibly work without callbacks, if possible.
.
(I have seen this related C++ example but I cannot find a way to implement the workflow for C#
https://support.gurobi.com/hc/en-us/articles/360054225092?input_string=terminate+optimization+in+c%23+application)
Thank you for your help.
Kind regards,
Jan Brütting
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
Hi Jan,
The key to do this is to terminate the optimization in the handler, and "alert" the main thread that the optimization has been manually interrupted.
You could try something like this without using callbacks:
using System;
using Gurobi;
public static class Globals
{
public static double objval = 0.0;
public static GRBEnv env = new GRBEnv();
public static GRBModel model;
public static bool manuallyInterrupted = false;
}
class mipexample_cs
{
public static void Main(string[] args)
{
Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);
try {
Globals.model = new GRBModel(Globals.env, "yourmodelfile.mps");
if (Globals.model.IsMIP == 0) {
Console.WriteLine("Model is not a MIP");
return;
}
Globals.model.Optimize();
if (Globals.manuallyInterrupted)
{
bool tryAgain = true;
/* query solve status until available and handle exception when not available */
while (tryAgain)
{
try
{
if (Globals.model.Status == GRB.Status.INTERRUPTED)
{
/* query solver data once solve is interrupted*/
Globals.objval = Globals.model.ObjVal;
}
Console.WriteLine(" OBJECTIVE = " + Globals.objval);
tryAgain = false;
}
catch (GRBException f)
{
/* the error output is optional */
Console.WriteLine("Gurobi Error code = " + f.ErrorCode);
Console.WriteLine(f.Message);
}
}
}
int optimstatus = Globals.model.Status;
double objvalint = 0;
if (optimstatus == GRB.Status.OPTIMAL) {
objvalint = Globals.model.ObjVal;
Console.WriteLine("Optimal objective: " + objvalint);
} else {
Console.WriteLine("Optimization was stopped with status = "
+ optimstatus);
return;
}
Globals.model.Dispose();
Globals.env.Dispose();
} catch (GRBException e) {
Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message);
}
return;
}
protected static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
Console.WriteLine("Program Terminated Manually");
Globals.manuallyInterrupted = true;
Globals.model.Terminate();
e.Cancel = true;
}
}0
Post is closed for comments.
Comments
2 comments