How to display a progress indicator for an external job?

已计划

Hi all,

I am working on a plug-in that needs to display a progress indicator for an external background task. We don't have direct control over the execution of this task. Instead, we get notifications about its progress (queued, running, finished, etc.).

The problem I am running into is that all the ways I've seen of displaying a progress indicator require the job's execution to start and finish within the task's run method.

ProgressManager.getInstance().run(new Task.Backgroundable(getProject(), "title", true) {
	@Override
	public void run(@NotNull ProgressIndicator progressIndicator) {
		runBackgroundJob();
		// Job is finished and progress indicator is removed when run() returns
	}
});

 Our plug-in historically reconciled this architectural difference with a sleep loop inside the run method, like this:

ProgressManager.getInstance().run(new Task.Backgroundable(getProject(), "title", true) {
	@Override
	public void run(@NotNull ProgressIndicator progressIndicator) {
		try {
		    while(!isExternalTaskDone()) {
		        Thread.sleep(200);
		    	progressIndicator.checkCanceled();
		    }
		catch (Exception ex) {
			return;
		}
		// Job is finished and progress indicator is removed when run() returns
	}
});

I'd like to avoid this kind of polling loop if possible, as it seems like a waste of CPU cycles to be continually polling like this.

One alternative method I've tried involved having the run() method wait for a Semaphore which would be released when we were notified that the external job was finished. This worked, but it broke the progress indicator cancel functionality, as that seems to get invoked on the same thread that run() executes on.

Ideally, I'd like to be able to control the lifespan of my progress indicator directly, but I'm not sure if this is possible with the available APIs.

Does anyone know of a better way of displaying a progress indicator for an external job?

1

请先登录再写评论。