How do I do this without using try/catch?
8 views (last 30 days)
I am using waitbar within Run_pushbutton_Callback (GUIDE GUI):
function Run_pushbutton_Callback(hObject, ~, handles)
wb = waitbar(0,'Computing...','Name','MyProgName');
wbch = allchild(wb);
jp = wbch(1).JavaPeer;
% call main function
handles.mainfunc(S); % S is structure of variables
close(wb); % close dialog box
close(wb); % close dialog box
errorMessage=sprintf('Error in function %s() at line %d.\n\nError Message:\n%s', ...
ME.stack(1).name, ME.stack(1).line, ME.message);
fprintf(2, '%s\n', errorMessage);
uiwait(errordlg(errorMessage)); % error dialog
% rethrow(ME); % rethrow the whole error message in command window (if needed)
When mainfunc() throws an error, waitbar still continues blinking - without try/catch. I used try/catch solution to close it. However, Matlab documentation says that the memory optimisation etc is not supported within try/catch: https://www.mathworks.com/help/matlab/matlab_prog/avoid-unnecessary-copies-of-data.html
Also, it looks a bit awkward to use try/catch for entire program.
- How can I close waitbar after error without using try/catch?
- How come that in-place or other optimisation does not work within a function and its subfunctions (not nested) if the function is within try/catch block?
Walter Roberson on 22 Aug 2021
To get rid of the try/catch for closing the waitbar, use
cleanMe = onCleanup(@() delete(wb));
If you put that within a function, you do not even need to remove the waitbar yourself when the iteration finishes -- the waitbar will be removed when the function returns normally. The waitbar will also be removed when the function is terminated because of error() and so the variables are being deleted.
(You can still delete the waitbar early if you want to, such as if you want to start a different waitbar.)
The reason that some optimizations are disabled within try/catch:
When you have a function without try/catch, then the implicit "contract" with the Execution Engine is that the Execution Engine will do the operations implied by the code and have the answer ready by the time the function returns.
Notice I did not say that the contract is that it will execute the lines in sequence: MATLAB is permitted to rewrite operations according to what the operations are supposed to "mean" instead of what the code lines say in detail.
For example if you have a loop that is doing
for K = 1 : 1E8
D(K) = A(K) + B(K) .* C(K);
then there is no "contract" that MATLAB will execute a loop 1E8 times and do one addition and one multiplication for each loop iteration: MATLAB is permitted to instead call into a high performance linear algebra "multiply and add" that can split up the iterations between cores and which might even use a hardware FMA (Fused Multiply and Add -- https://en.wikipedia.org/wiki/Multiply%E2%80%93accumulate_operation ) . Or which might not for sutble precision reasons, but the high performance code might know how to stick the ADD in the Branch Delay Slot and so more or less "get it for free" .
There are cases where MATLAB is able to recognize that a particular operation something like W * X * W' implies some properties of the resulting matrix and because of that is able to take more efficient calculation pathways on some other operations on the same line. Likewise in theory if MATLAB recognized that a particular operation should return a symmetric result, then MATLAB is permitted to only actually do one triangle of it and fill in the second half from the results of the first half.
There is a "contract" with the programmer that at the time an Catch exception is taken, that variables will be in a state as if the lines had been performed as written until the place of the exception. And MATLAB finds that the easiest way to achive that sometimes is to disable some of the optimizations within a try/catch.
In theory the restriction should only apply to code that appears directly inside the try block, along with telling any called routines that do in-place overwriting that they are not permitted to do that for the variables that are in scope at the time of the try. Nested functions can share variables so they might have to be throttled. But called functions that do not do in-place optimization do not have to be throttled, because they have their own contracts and their internal variables that might be out-of-phase cannot get returned back to the caller in the case of an exception in the called routine.