Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Rich Client Platform (RCP) » help on status manager and (a)syncExec
help on status manager and (a)syncExec [message #555997] Mon, 30 August 2010 14:01 Go to next message
Luca Ferrari is currently offline Luca FerrariFriend
Messages: 159
Registered: November 2009
Senior Member
Hi all,
in my rcp application I've got the following call chain:
 MyTableViewer -> MyContentProvider -> MyDao.loadElementsFromDatabase()


so each time the table view is created and displayed, it asks the content provider to provide the content, and the latter asks to a DAO to load the data from the database. I'd like to notify the user about what is happening within the DAO logic, so I created a wrapper for a status line manager that is used directly from within the DAO thru the following method:
 public void setMessage(final String message) {
	PlatformUI.getWorkbench().getDisplay().syncExec( new Runnable(){

	    public void run() {
		statusLineManager.setMessage(message);
	    }
	    
	});
	
    }



The problem is that the message is never displayed and a little debugging shows that the thread that is executing the
statusLineManager.setMessage(message);
is the "main" thread, is this correct? How can I get the status line displaying messages from the DAO in sync?

Thanks.
Re: help on status manager and (a)syncExec [message #556018 is a reply to message #555997] Mon, 30 August 2010 14:34 Go to previous messageGo to next message
David Wegener is currently offline David WegenerFriend
Messages: 1351
Registered: July 2009
Senior Member
"Luca Ferrari" <fluca1978@infinito.it> wrote in message
news:i5gdk1$qs5$1@build.eclipse.org...
> Hi all,
> in my rcp application I've got the following call chain:
>
> MyTableViewer -> MyContentProvider -> MyDao.loadElementsFromDatabase()
>
>
> so each time the table view is created and displayed, it asks the content
> provider to provide the content, and the latter asks to a DAO to load the
> data from the database. I'd like to notify the user about what is
> happening within the DAO logic, so I created a wrapper for a status line
> manager that is used directly from within the DAO thru the following
> method:
>
> public void setMessage(final String message) {
> PlatformUI.getWorkbench().getDisplay().syncExec( new Runnable(){
>
> public void run() {
> statusLineManager.setMessage(message);
> }
> });
>
> }
>
>
>
> The problem is that the message is never displayed and a little debugging
> shows that the thread that is executing the
> statusLineManager.setMessage(message); is the "main" thread, is this
> correct? How can I get the status line displaying messages from the DAO in
> sync?
>
> Thanks.

You need to fork off the call to the DAO in another thread. You can use the
Eclipse Job API to do this. That will free up the GUI thread to handle
other tasks such as displaying your status update.
Re: help on status manager and (a)syncExec [message #556274 is a reply to message #556018] Tue, 31 August 2010 14:59 Go to previous messageGo to next message
Luca Ferrari is currently offline Luca FerrariFriend
Messages: 159
Registered: November 2009
Senior Member
The problem is that my DAO returns a list of objects that must be displayed in the view, so the call to the DAO cannot be async or done by another thread. Someone can better explain how to do this?
Re: help on status manager and (a)syncExec [message #556339 is a reply to message #556274] Tue, 31 August 2010 20:44 Go to previous messageGo to next message
David Wegener is currently offline David WegenerFriend
Messages: 1351
Registered: July 2009
Senior Member
"Luca Ferrari" <fluca1978@infinito.it> wrote in message
news:i5j5c7$d16$1@build.eclipse.org...
> The problem is that my DAO returns a list of objects that must be
> displayed in the view, so the call to the DAO cannot be async or done by
> another thread. Someone can better explain how to do this?

There isn't another way to do it. In order for the user interface to get
updated, the Display thread has to continue. If the Display thread is
waiting in your code for the return from the DAO, it can't update the UI.

You need to fork off a thread. In that thread call the DAO. When the DAO
returns, create a runnable whose run method processes the results and
populates the view. Pass this to the Display.asyncExec call.
Re: help on status manager and (a)syncExec [message #558428 is a reply to message #556339] Sun, 12 September 2010 19:01 Go to previous messageGo to next message
Luca Ferrari is currently offline Luca FerrariFriend
Messages: 159
Registered: November 2009
Senior Member
Uhm...I'm still fighting with such problem, does anybody has a template or a good tutorial on how to achieve my aim with the update-from-dao of the progress bar? I'm quite confused.

Thanks
Re: help on status manager and (a)syncExec [message #632060 is a reply to message #558428] Mon, 11 October 2010 12:18 Go to previous messageGo to next message
Luca Ferrari is currently offline Luca FerrariFriend
Messages: 159
Registered: November 2009
Senior Member
I think I've almost done:
1) I created a "worker" thread that in its run method loads all the data from the DAO and calls inputChanged on the content provider
2) whithin the content provider I've got an asyncExec that sets the data into the viewer and forces a refresh:

public void inputChanged(final Viewer viewer, Object oldInput, final Object newInput) {
	
	PlatformUI.getWorkbench().getDisplay().asyncExec( new Runnable(){

	    @Override
	    public void run() {
                ....
		viewer.refresh();
		
	    }
	   
	    
	});
	
	
	
    }


The problem now is that, when the application is closed, I got an exception about the viewer.refresh() call saying that the widget is disposed. The problem is that I don't know what view is exactly disposed and why....any help or possible explaination?

Thanks

org.eclipse.swt.SWTException: Failed to execute runnable (org.eclipse.swt.SWTException: Widget is disposed)
	at org.eclipse.swt.SWT.error(SWT.java:4083)
	at org.eclipse.swt.SWT.error(SWT.java:3998)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:137)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3515)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3164)
	at org.eclipse.swt.widgets.Display.release(Display.java:3215)
	at org.eclipse.swt.graphics.Device.dispose(Device.java:237)
	at hrpm.rcp.Application.start(Application.java:31)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1407)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1383)
Caused by: org.eclipse.swt.SWTException: Widget is disposed
	at org.eclipse.swt.SWT.error(SWT.java:4083)
	at org.eclipse.swt.SWT.error(SWT.java:3998)
	at org.eclipse.swt.SWT.error(SWT.java:3969)
	at org.eclipse.swt.widgets.Widget.error(Widget.java:466)
	at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:403)
	at org.eclipse.swt.widgets.Table.deselectAll(Table.java:956)
	at org.eclipse.jface.viewers.TableViewer.doDeselectAll(TableViewer.java:277)
	at org.eclipse.jface.viewers.AbstractTableViewer.setSelectionToWidget(AbstractTableViewer.java:908)
	at org.eclipse.jface.viewers.StructuredViewer.setSelectionToWidget(StructuredViewer.java:1741)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1429)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1383)
	at org.eclipse.jface.viewers.StructuredViewer.refresh(StructuredViewer.java:1485)
	at org.eclipse.jface.viewers.ColumnViewer.refresh(ColumnViewer.java:537)
	at org.eclipse.jface.viewers.StructuredViewer.refresh(StructuredViewer.java:1444)
	at hrpm.rcp.gui.providers.content.BaseTableContentProvider$1.run(BaseTableContentProvider.java:224)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
	... 18 more
Re: help on status manager and (a)syncExec [message #632063 is a reply to message #632060] Mon, 11 October 2010 12:22 Go to previous messageGo to next message
Daniel Krügler is currently offline Daniel KrüglerFriend
Messages: 853
Registered: July 2009
Senior Member
On 11.10.2010 14:18, Luca Ferrari wrote:
> I think I've almost done:
> 1) I created a "worker" thread that in its run method loads all the data
> from the DAO and calls inputChanged on the content provider
> 2) whithin the content provider I've got an asyncExec that sets the data
> into the viewer and forces a refresh:
>
>
> public void inputChanged(final Viewer viewer, Object oldInput, final
> Object newInput) {
>
> PlatformUI.getWorkbench().getDisplay().asyncExec( new Runnable(){
>
> @Override
> public void run() {
> ....
> viewer.refresh();
>
> }
> });
>
>
>
> }
>
>
> The problem now is that, when the application is closed, I got an
> exception about the viewer.refresh() call saying that the widget is
> disposed. The problem is that I don't know what view is exactly disposed
> and why....any help or possible explaination?

This situation may always occur with an asyncExec call, because you
don't know when your runnable will be called. Always check first in such
a runnable whether your widget is not already disposed. If so, just
handle this is noop (i.e. exit the runnable).

HTH & Greetings from Bremen,

Daniel Krügler
Re: help on status manager and (a)syncExec [message #632481 is a reply to message #632063] Wed, 13 October 2010 06:59 Go to previous messageGo to next message
Luca Ferrari is currently offline Luca FerrariFriend
Messages: 159
Registered: November 2009
Senior Member
Ok, this is strange, but what is the way to test if a viewer has been disposed? I don't find a isDisposed() method in the Viewer class, so I tried with
viewer.getControl().isDisposed()

but it does not work.
Any suggestion?

Thanks,
Luca
Re: help on status manager and (a)syncExec [message #632555 is a reply to message #632481] Wed, 13 October 2010 12:16 Go to previous messageGo to next message
Daniel Krügler is currently offline Daniel KrüglerFriend
Messages: 853
Registered: July 2009
Senior Member
On 13.10.2010 08:59, Luca Ferrari wrote:
> Ok, this is strange, but what is the way to test if a viewer has been
> disposed? I don't find a isDisposed() method in the Viewer class, so I
> tried with viewer.getControl().isDisposed()
> but it does not work.
> Any suggestion?

What does "it does not work" mean? What Viewer class are you using?
I assume there must be a stacktrace that points to the affected widget,
so which one complains?

- Daniel
Re: help on status manager and (a)syncExec [message #632766 is a reply to message #632555] Thu, 14 October 2010 08:33 Go to previous messageGo to next message
Luca Ferrari is currently offline Luca FerrariFriend
Messages: 159
Registered: November 2009
Senior Member
I meant that the application was still raising the exception on exit, but it was my fault: I was testing for disposal before "scheduling" the asyncExce while it is required to test within the asyncExce runnable. That's my fault!

However, now that I guess I've understood the asyncExec a little more, does it make sense to use a thread to load the elements and execute a runnable instead of using a Job scheduled immediately?
Re: help on status manager and (a)syncExec [message #632815 is a reply to message #632766] Thu, 14 October 2010 10:45 Go to previous message
Daniel Krügler is currently offline Daniel KrüglerFriend
Messages: 853
Registered: July 2009
Senior Member
On 14.10.2010 10:33, Luca Ferrari wrote:
> However, now that I guess I've understood the asyncExec a little more,
> does it make sense to use a thread to load the elements and execute a
> runnable instead of using a Job scheduled immediately?

I think the basic guide-line should be:

1) If you need to interact with the UI, use asyncExec

2) If your work has considerable parts that are UI-independent, use
a job for this. You will run in problematic situations, when
you have several dependent work units of the form

UI -> non-UI -> UI -> non-UI ->...

etc. If possible, try to isolate UI and non-UI work-units in as large
blocks as possible to prevent the overhead of an unnecessary high
number of context switching.

UIJob is somewhat in-between. I use it only, if I need to.

HTH & Greetings from Bremen,

- Daniel
Previous Topic:IWorkbenchConfigurer->setSaveAndRestore and perspectives.
Next Topic:Enable/disable commands
Goto Forum:
  


Current Time: Thu Dec 18 04:12:14 GMT 2014

Powered by FUDForum. Page generated in 0.01963 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software