.NET/Link Example: A "Nice" Function (Setting the Kernel Process Priority)

This is a very simple example demonstrating some basic .NET/Link programming. One nice use for .NET/Link is to get closer to the operating system level than Mathematica normally allows. Here we use some .NET classes for controlling processes.

This example presents a function called Nice, which lowers the Mathematica kernel process' priority during the execution of its argument. It is reminiscent of the Unix command nice.

To try this example, evaluate all the initialization cells (you can do this with the menu command Kernel/Evaluation/Evaluate Initialization). Then go to the Example section.

Code and Explanation

This example demonstrates a typical structure for a .NET/Link program:
     - It does not need to return any .NET objects, so it wraps the entire computation in NETBlock, which allows all objects created during the running of the program to be released when it ends.
     - It calls InstallNET at the start to ensure that .NET is running.

Needs["NETLink`"];

SetAttributes[Nice, HoldFirst];

Nice[expr_] :=
	NETBlock[
		Module[{kernelProc, origPriority, result},
			InstallNET[];
			(* We need to call a static member from this class (the GetProcessById method),
			   so we ned to use LoadNETType to load the class.
			*)
			LoadNETType["System.Diagnostics.Process"];
			kernelProc = Process`GetProcessById[$ProcessID];
			(* Here we get the PriorityClass property of the kernel's Process object. *)
			origPriority = kernelProc@PriorityClass;
			CheckAbort[
				(* Set the priortiy to Idle level. Although we are accessing a static member (the Idle value
				   from the ProcessPriorityClass enum), we do not need to call LoadNETType on the enum class
				   because it was already loaded when we returned the kernelProc@PriorityClass object above.
				*)
				kernelProc@PriorityClass = ProcessPriorityClass`Idle;
				(* Perform the computation. *)
				result = expr;
				(* Restore the original priority. *)
				kernelProc@PriorityClass = origPriority;
				result,
			(* If aborted *)
				(* We are careful to restore the original priority if aborted. *)
				kernelProc@PriorityClass = origPriority;
				$Aborted
			]
		]
	]

Example

Here is a time-consuming call that we can wrap in Nice. The integration will eventually fail to converge after 5000000 iterations. The computer's CPU meter will remain pegged while this is running, but any other operations you perform on the computer will take priority over the computation.

Nice[
	NIntegrate[x^2/(Cos[x + y + 1] + 5), {x, 0, 5}, {y, 0, 5}, PrecisionGoal -> 50, MaxPoints -> 5000000]
]