Package com._1c.g5.v8.dt.common.runtime
Class ProgressMonitors
java.lang.Object
com._1c.g5.v8.dt.common.runtime.ProgressMonitors
Utilities to work with tasks, sub-tasks and progress monitors.
The contracts of
IProgressMonitor
and SubMonitor
are not easy to understand and follow correctly. Frequently their API is misused.
The goal of the class is to make it simple to correctly follow the contract
anticipated by Eclipse developers.
- Use
computeAsTask(java.lang.String, int, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.ComputableWithSubMonitor<T, E1, E2>)
/runAsTask(java.lang.String, int, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.RunnableWithSubMonitor<E1, E2>)
at the top of the stack in action handler, event handler or a job to denote start of a task. - Use
computeWithSubMonitor(java.lang.String, int, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.ComputableWithSubMonitor<T, E1, E2>)
/runWithSubMonitor(java.lang.String, int, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.RunnableWithSubMonitor<E1, E2>)
whenever you getIProgressMonitor
as a method parameter and do with it something more than just passing it through to a single other method. Specify a name in potentially long running methods of public API of services to denote sub-task start. Otherwise, leave name asnull
. - Use
computeInSubTask(java.lang.String, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.SimpleComputableSubTask<T, E1, E2>)
/runInSubTask(java.lang.String, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.SimpleRunnableSubTask<E1, E2>)
when you have multiple long steps in a current method to denote separate sub-tasks. Usually sub-tasks reflect structure of a task rather than processing of multiple resources in a batch. - Use
computeInStep(java.lang.String, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.SimpleComputableSubTask<T, E1, E2>)
/runInStep(java.lang.String, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.SimpleRunnableSubTask<E1, E2>)
when you have a number of items to process as a part of a sub-task. While sub-tasks reflect structure of a task, it is step that represents processing of individual item like a file, resource, configuration object and so on within a set of multiple such items.
- Those that start with run return no value, just execute some action.
- Those that start with compute return a value so you have to pass something that returns it too.
CommonPlugin.TRACE_DEBUG
, CommonPlugin.TRACE_PROGRESS_TASKS
,
CommonPlugin.TRACE_PROGRESS_SUBTASKS
and CommonPlugin.TRACE_PROGRESS_STEPS
then a record will be logged when task, sub-task or step starts or ends and how long it took to run it.
If CommonPlugin.isDebugging()
is enabled then potential issues with progress reporting
will be logged as warnings.-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interface
Block of code that is part of task or subtask working withIProgressMonitor
to compute a value.static interface
ProgressMonitors.RunnableWithSubMonitor<E1 extends Throwable,
E2 extends Throwable> Block of code that is part of task or subtask working withIProgressMonitor
to execute an action.static interface
Block of code computing a value in a subtask that does not call other methods usingIProgressMonitor
.static interface
ProgressMonitors.SimpleRunnableSubTask<E1 extends Throwable,
E2 extends Throwable> Block of code running an action in a subtask that does not call other methods usingIProgressMonitor
. -
Method Summary
Modifier and TypeMethodDescriptioncomputeAsTask
(String name, int childrenTicks, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.ComputableWithSubMonitor<T, E1, E2> codeBlock) Begins a task that computes a value.computeInStep
(String name, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.SimpleComputableSubTask<T, E1, E2> codeBlock) Wraps code block computing a value with a step of a sub-task.computeInSubTask
(String name, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.SimpleComputableSubTask<T, E1, E2> codeBlock) Wraps code block computing a value with a sub-task.computeWithSubMonitor
(String name, int childrenTicks, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.ComputableWithSubMonitor<T, E1, E2> codeBlock) Computes a value using sub-monitor.runAsTask
(String name, int childrenTicks, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.RunnableWithSubMonitor<E1, E2> codeBlock) Begins a task that runs an action.runInStep
(String name, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.SimpleRunnableSubTask<E1, E2> codeBlock) Wraps code block running an action with a step of a sub-task.runInSubTask
(String name, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.SimpleRunnableSubTask<E1, E2> codeBlock) Wraps code block running an action with a sub-task.runWithSubMonitor
(String name, int childrenTicks, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.RunnableWithSubMonitor<E1, E2> codeBlock) Runs an action using sub-monitor.
-
Method Details
-
computeAsTask
public static <T,E1 extends Throwable, T computeAsTaskE2 extends Throwable> (String name, int childrenTicks, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.ComputableWithSubMonitor<T, E1, throws E1, E2E2> codeBlock) Begins a task that computes a value. The method should be called at the top of the stack where a task actually begins. This is usually either job, action handler or event handler. The method should not be called multiple times for the same root progress monitor. You should not generally call the method from service implementations, protected methods and so on where you do not control if task has already began. For sub-tasks seecomputeInSubTask(java.lang.String, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.SimpleComputableSubTask<T, E1, E2>)
. Calling the method, creates newSubMonitor
from the specifiedIProgressMonitor
, allocates ticks for childrens and sets name of the task. An actual code to run will get this sub-monitor as a parameter and should use it instead of the original progress monitor. Both original monitor and sub-monitor automatically getIProgressMonitor.done()
before the method returns (successfully or erroneously). When calling another method inside the code block and have to pass to this method an instance ofIProgressMonitor
then use eitherSubMonitor.newChild(int)
/SubMonitor.split(int)
(using the sub monitor you have received as a parameter of the code block) orcomputeWithSubMonitor(java.lang.String, int, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.ComputableWithSubMonitor<T, E1, E2>)
/computeInSubTask(java.lang.String, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.SimpleComputableSubTask<T, E1, E2>)
. Avoid usingIProgressMonitor.slice(int)
on sub monitor as it behaves not exactly straightforward. PreferSubMonitor.split(int)
as it automatically checks for cancellation and will throwOperationCanceledException
.progressMonitorDialog.run(true, true, monitor -> { int result = ProgressMonitors.computeAsTask(Messages.Task1_name, 100, monitor, subMonitor -> { method1(subMonitor.newChild(10)); method2(subMonitor.newChild(10)); return method3(subMonitor.newChild(80)); }); });
- Type Parameters:
T
- Type of the returned value.E1
- Type of Exception thrown.E2
- Type of Exception thrown.- Parameters:
name
- Name of the task being started. This should be a localized string that could be presented to user. Must not benull
.childrenTicks
- Number of ticks to allocate for childred. UseIProgressMonitor.UNKNOWN
if you do not know amount of work.monitor
- Parent progress monitor ornull
if was none or nothing is to be reported. This monitor should not be used inside the code block or by caller once the method returns.codeBlock
- Code that computes a value. It gets new sub-monitor as a parameter. Must not benull
.- Returns:
- The same value as the code block returns.
- Throws:
E1
- The same exception as the code block throws.E2
- The same exception as the code block throws.
-
runAsTask
public static <E1 extends Throwable,E2 extends Throwable> void runAsTask(String name, int childrenTicks, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.RunnableWithSubMonitor<E1, E2> codeBlock) throws E1, E2Begins a task that runs an action. The method should be called at the top of the stack where a task actually begins. This is usually either job, action handler or event handler. The method should not be called multiple times for the same root progress monitor. You should not generally call the method from service implementations, protected methods and so on where you do not control if task has already began. For sub-tasks seecomputeInSubTask(java.lang.String, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.SimpleComputableSubTask<T, E1, E2>)
. Calling the method, creates newSubMonitor
from the specifiedIProgressMonitor
, allocates ticks for childrens and sets name of the task. An actual code to run will get this sub-monitor as a parameter and should use it instead of the original progress monitor. Both original monitor and sub-monitor automatically getIProgressMonitor.done()
before the method returns (successfully or erroneously). When calling another method inside the code block and have to pass to this method an instance ofIProgressMonitor
then use eitherSubMonitor.newChild(int)
/SubMonitor.split(int)
(using the sub monitor you have received as a parameter of the code block) orrunWithSubMonitor(java.lang.String, int, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.RunnableWithSubMonitor<E1, E2>)
/runInSubTask(java.lang.String, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.SimpleRunnableSubTask<E1, E2>)
. Avoid usingIProgressMonitor.slice(int)
on sub monitor as it behaves not exactly straightforward. PreferSubMonitor.split(int)
as it automatically checks for cancellation and will throwOperationCanceledException
.progressMonitorDialog.run(true, true, monitor -> { ProgressMonitors.runAsTask(Messages.Task1_name, 100, monitor, subMonitor -> { method1(subMonitor.newChild(10)); method2(subMonitor.newChild(10)); method3(subMonitor.newChild(80)); }); });
- Type Parameters:
E1
- Type of Exception thrown.E2
- Type of Exception thrown.- Parameters:
name
- Name of the task being started. This should be a localized string that could be presented to user. Must not benull
.childrenTicks
- Number of ticks to allocate for childred. UseIProgressMonitor.UNKNOWN
if you do not know amount of work.monitor
- Parent progress monitor ornull
if was none or nothing is to be reported. This monitor should not be used inside the code block or by caller once the method returns.codeBlock
- An action to run. It gets new sub-monitor as a parameter. Must not benull
.- Throws:
E1
- The same exception as the code block throws.E2
- The same exception as the code block throws.
-
computeWithSubMonitor
public static <T,E1 extends Throwable, T computeWithSubMonitorE2 extends Throwable> (String name, int childrenTicks, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.ComputableWithSubMonitor<T, E1, throws E1, E2E2> codeBlock) Computes a value using sub-monitor. The method should wrap body of methods receivingIProgressMonitor
. It creates childSubMonitor
that is passed as a parameter to the wrapped code block. Both original parent progress monitor and newly created child sub-monitor automatically getIProgressMonitor.done()
before the method returns (successfully or erroneously). If name was specified then it will be set as a sub-task name before the code block is executed. In this case, once the code block finishes execution, sub-task name will be reset (to an empty string rather than to an old sub-task name). Because of this, consider specifying the name when implementing public API methods of services when they take long time to execute but avoid specifying name for non-public methods and non-services to avoid unintently resetting sub-task name because of something short and unimportant. When calling another method inside the code block and have to pass to this method an instance ofIProgressMonitor
then use eitherSubMonitor.newChild(int)
/SubMonitor.split(int)
(using the sub monitor you have received as a parameter of the code block) orcomputeWithSubMonitor(java.lang.String, int, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.ComputableWithSubMonitor<T, E1, E2>)
/computeInSubTask(java.lang.String, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.SimpleComputableSubTask<T, E1, E2>)
. Avoid usingIProgressMonitor.slice(int)
on sub monitor as it behaves not exactly straightforward. PreferSubMonitor.split(int)
as it automatically checks for cancellation and will throwOperationCanceledException
.public int myPublicApiMethod(IProgressMonitor monitor) { return computeWithSubMonitor(Messages.Subtask1_name, 100, monitor, subMonitor -> { method1(subMonitor.newChild(10)); method2(subMonitor.newChild(10)); return method3(subMonitor.newChild(80)); }); } private int somePrivateMethod(IProgressMonitor monitor) { return computeWithSubMonitor(null, 1, monitor, subMonitor -> { return otherClassInstance.otherMethod(subMonitor.newChild(1)); }); }
- Type Parameters:
T
- Type of the returned value.E1
- Type of Exception thrown.E2
- Type of Exception thrown.- Parameters:
name
- Name of the sub-task being started (case of service public API that runs for long) ornull
if sub-task name is not to be affected (everything else). If notnull
then this should be a localized string that could be presented to user.childrenTicks
- Number of ticks to allocate for childred. UseIProgressMonitor.UNKNOWN
if you do not know amount of work.monitor
- Parent progress monitor ornull
if was none or nothing is to be reported. This monitor should not be used inside the code block or by caller once the method returns.codeBlock
- Code that computes a value. It gets new sub-monitor as a parameter. Must not benull
.- Returns:
- The same value as the code block returns.
- Throws:
E1
- The same exception as the code block throws.E2
- The same exception as the code block throws.
-
runWithSubMonitor
public static <E1 extends Throwable,E2 extends Throwable> void runWithSubMonitor(String name, int childrenTicks, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.RunnableWithSubMonitor<E1, E2> codeBlock) throws E1, E2Runs an action using sub-monitor. The method should wrap body of methods receivingIProgressMonitor
. It creates childSubMonitor
that is passed as a parameter to the wrapped code block. Both original parent progress monitor and newly created child sub-monitor automatically getIProgressMonitor.done()
before the method returns (successfully or erroneously). If name was specified then it will be set as a sub-task name before the code block is executed. In this case, once the code block finishes execution, sub-task name will be reset (to an empty string rather than to an old sub-task name). Because of this, consider specifying the name when implementing public API methods of services when they take long time to execute but avoid specifying name for non-public methods and non-services to avoid unintently resetting sub-task name because of something short and unimportant. When calling another method inside the code block and have to pass to this method an instance ofIProgressMonitor
then use eitherSubMonitor.newChild(int)
/SubMonitor.split(int)
(using the sub monitor you have received as a parameter of the code block) orrunWithSubMonitor(java.lang.String, int, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.RunnableWithSubMonitor<E1, E2>)
/runInSubTask(java.lang.String, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.SimpleRunnableSubTask<E1, E2>)
. Avoid usingIProgressMonitor.slice(int)
on sub monitor as it behaves not exactly straightforward. PreferSubMonitor.split(int)
as it automatically checks for cancellation and will throwOperationCanceledException
.public void myPublicApiMethod(IProgressMonitor monitor) { runWithSubMonitor(Messages.Subtask1_name, 100, monitor, subMonitor -> { method1(subMonitor.newChild(10)); method2(subMonitor.newChild(10)); method3(subMonitor.newChild(80)); }); } private void somePrivateMethod(IProgressMonitor monitor) { runWithSubMonitor(null, 1, monitor, subMonitor -> { otherClassInstance.otherMethod(subMonitor.newChild(1)); }); }
- Type Parameters:
E1
- Type of Exception thrown.E2
- Type of Exception thrown.- Parameters:
name
- Name of the sub-task being started (case of service public API that runs for long) ornull
if sub-task name is not to be affected (everything else). If notnull
then this should be a localized string that could be presented to user.childrenTicks
- Number of ticks to allocate for childred. UseIProgressMonitor.UNKNOWN
if you do not know amount of work.monitor
- Parent progress monitor ornull
if was none or nothing is to be reported. This monitor should not be used inside the code block or by caller once the method returns.codeBlock
- An action to run. It gets new sub-monitor as a parameter. Must not benull
.- Throws:
E1
- The same exception as the code block throws.E2
- The same exception as the code block throws.
-
computeInSubTask
public static <T,E1 extends Throwable, T computeInSubTaskE2 extends Throwable> (String name, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.SimpleComputableSubTask<T, E1, throws E1, E2E2> codeBlock) Wraps code block computing a value with a sub-task. The method does not manage creation or work done of parent or child monitors. Moreover, no child monitor is created. The only thing done is setting sub-task name before the code block is executed and then clearing sub-task name after the code block has finished executing (successfully or erroneously). This clearing of sub-task name is important to ensure that user is not confused seeing task name that has been actually finished long ago while waiting for something else. The method could be useful when running a long computation right inside the current method:int result1 = ProgressMonitors.computeInSubTask(Messages.Subtask1_name, monitor, () -> { Thread.sleep(1000); return 1; }); int result2 = ProgressMonitors.computeInSubTask(Messages.Subtask2_name, monitor, () -> { Thread.sleep(1000); return 2; });
- Type Parameters:
T
- Type of the returned value.E1
- Type of Exception thrown.E2
- Type of Exception thrown.- Parameters:
name
- Name of the sub-task being started. This should be a localized string that could be presented to user. Must not benull
.monitor
- Progress monitor with which to report subtask ornull
if was none or nothing is to be reported (the code block is executed anyway).codeBlock
- Code that computes a value. Must not benull
.- Returns:
- The same value as the code block returns.
- Throws:
E1
- The same exception as the code block throws.E2
- The same exception as the code block throws.
-
runInSubTask
public static <E1 extends Throwable,E2 extends Throwable> void runInSubTask(String name, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.SimpleRunnableSubTask<E1, E2> codeBlock) throws E1, E2Wraps code block running an action with a sub-task. The method does not manage creation or work done of parent or child monitors. Moreover, no child monitor is created. The only thing done is setting sub-task name before the code block is executed and then clearing sub-task name after the code block has finished executing (successfully or erroneously). This clearing of sub-task name is important to ensure that user is not confused seeing task name that has been actually finished long ago while waiting for something else. The method could be useful when running a long action right inside the current method:ProgressMonitors.runInSubTask(Messages.Subtask1_name, monitor, () -> { Thread.sleep(1000); }); ProgressMonitors.runInSubTask(Messages.Subtask2_name, monitor, () -> { Thread.sleep(1000); });
- Type Parameters:
E1
- Type of Exception thrown.E2
- Type of Exception thrown.- Parameters:
name
- Name of the task being started. This should be a localized string that could be presented to user. Must not benull
.monitor
- Progress monitor with which to report subtask ornull
if was none or nothing is to be reported (the code block is executed anyway).codeBlock
- Code that runs an action. Must not benull
.- Throws:
E1
- The same exception as the code block throws.E2
- The same exception as the code block throws.
-
computeInStep
public static <T,E1 extends Throwable, T computeInStepE2 extends Throwable> (String name, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.SimpleComputableSubTask<T, E1, throws E1, E2E2> codeBlock) Wraps code block computing a value with a step of a sub-task. WhilecomputeInSubTask(java.lang.String, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.SimpleComputableSubTask<T, E1, E2>)
should be used to reflect structure of the task, this method should be used to wrap arbitrary potentially high number of steps within a sub-task. For example, updating infobase (task) could involve exporting configuration (sub-task) and each file to export is a step that could be wrapped with this method. The rules for tracking tasks, sub-tasks and steps within sub-tasks could be different. The method does not manage creation or work done of parent or child monitors. Moreover, no child monitor is created. The only thing done is setting sub-task name before the code block is executed and then clearing sub-task name after the code block has finished executing (successfully or erroneously). This clearing of sub-task name is important to ensure that user is not confused seeing task name that has been actually finished long ago while waiting for something else. The method could be useful when reporting execution of high number of steps:for(File file : files) { int result = ProgressMonitors.computeInStep(file.toString(), monitor, () -> { processFile(file); }); }
- Type Parameters:
T
- Type of the returned value.E1
- Type of Exception thrown.E2
- Type of Exception thrown.- Parameters:
name
- Name of the step being started. This should be a localized string that could be presented to user. Must not benull
.monitor
- Progress monitor with which to report subtask ornull
if was none or nothing is to be reported (the code block is executed anyway).codeBlock
- Code that computes a value. Must not benull
.- Returns:
- The same value as the code block returns.
- Throws:
E1
- The same exception as the code block throws.E2
- The same exception as the code block throws.
-
runInStep
public static <E1 extends Throwable,E2 extends Throwable> void runInStep(String name, org.eclipse.core.runtime.IProgressMonitor monitor, ProgressMonitors.SimpleRunnableSubTask<E1, E2> codeBlock) throws E1, E2Wraps code block running an action with a step of a sub-task. WhilerunInSubTask(java.lang.String, org.eclipse.core.runtime.IProgressMonitor, com._1c.g5.v8.dt.common.runtime.ProgressMonitors.SimpleRunnableSubTask<E1, E2>)
should be used to reflect structure of the task, this method should be used to wrap arbitrary potentially high number of steps within a sub-task. For example, updating infobase (task) could involve exporting configuration (sub-task) and each file to export is a step that could be wrapped with this method. The rules for tracking tasks, sub-tasks and steps within sub-tasks could be different. The method does not manage creation or work done of parent or child monitors. Moreover, no child monitor is created. The only thing done is setting sub-task name before the code block is executed and then clearing sub-task name after the code block has finished executing (successfully or erroneously). This clearing of sub-task name is important to ensure that user is not confused seeing task name that has been actually finished long ago while waiting for something else. The method could be useful when reporting execution of high number of steps:for(File file : files) { ProgressMonitors.runInStep(file.toString(), monitor, () -> { processFile(file); }); }
- Type Parameters:
E1
- Type of Exception thrown.E2
- Type of Exception thrown.- Parameters:
name
- Name of the task being started. This should be a localized string that could be presented to user. Must not benull
.monitor
- Progress monitor with which to report subtask ornull
if was none or nothing is to be reported (the code block is executed anyway).codeBlock
- Code that runs an action. Must not benull
.- Throws:
E1
- The same exception as the code block throws.E2
- The same exception as the code block throws.
-