# Eclipse UI blockiert - laengere Ablaeufe auf dem main-Thread..?



## sirbender (28. Jan 2010)

Hi,

ich versuche gerade ein Eclipse plug-in zu verbessern, dass von anderen geschrieben wurde. Es wir bei diesem plug-in ein Eclipse Remote Projekt angelegt. Es ist so implementiert, dass Eclipse nicht merkt, dass es sich um ein Remote-Filesystem handelt. Die Kommunikation/Filesynchronisierung geschieht ueber SFTP.

Das Problem ist, dass einige dieser recht langen File-Operationen von dem Programmierer scheinbar im main-Thread ausgefuehrt werden und wie ich annehme die UI deswegen nicht neu gezeichnet wird.

Generell meine Frage: ist es legal Operationen in Eclipse auf dem main-Thread auszufuehren? Wird dazu geraten eher Worker zu starten? Was sind da so die Regeln/Empfehlungen?

Danke!


----------



## Wildcard (28. Jan 2010)

*verschoben*
Eclipse hat bereits API um Remote Dateisysteme einzubinden. Die entsprechende Abstraktionsschicht heißt EFS (Eclipse File System).
Long Running Operations werden üblicherweise in einem Eclipse Job ausgeführt. Bei Dingen wie aufklappen der Verzeichnisstruktur (was bei Remote Dateisystemen länger dauern kann) gibt es ebenfalls unterstützung für asynchrone Ausführung. Hier kommen dann LazyContentProvider zum Einsatz.


----------



## sirbender (28. Jan 2010)

Ich weiss ueber das EFS Bescheid. Es wird auch in dem Plug-in genutzt. Das Problem ist folgendes:

Soll ein File remotely ausgeschrieben werden, ruft FileSystemResourceManager in seiner write-Methode folgenden code auf:
OutputStream out = store.openOutputStream(options, Policy.subMonitorFor(monitor, 0));

Dieser Ausruf geschieht im main Thread und will einen OutputStream in den es schreiben kann. Diesen OutputStream muss ich selbst erstellen und zurueckliefern. Wie also soll ich dem Aufrufer sagen, dass er doch bitte nicht im main-Thread in the OutputStream schreibt den ich ihm gebe sondern z.B. in einem extra Worker-Thread bzw. via LazyContentProvider?




org.eclipse.core.internal.localstore.FileSystemResourceManager.write(FileSystemResourceManager.java:962)
org.eclipse.core.internal.localstore.FileSystemResourceManager.internalWrite(FileSystemResourceManager.java:539)
org.eclipse.core.internal.resources.Project.writeDescription(Project.java:1196)
org.eclipse.core.internal.resources.Project.setDescription(Project.java:1085)
org.eclipse.core.internal.resources.Project.setDescription(Project.java:1109)
org.eclipse.cdt.make.internal.core.BuildInfoFactory$BuildInfoProject.putString(BuildInfoFactory.java:490)
org.eclipse.cdt.make.internal.core.BuildInfoFactory$AbstractBuildInfo.setBuildAttribute(BuildInfoFactory.java:99)


----------



## Wildcard (29. Jan 2010)

Seltsam das der cdt Builder im Main Thread abläuft. Wie wurde die aktion getriggert? Durch eine UI Aktion? Wenn ja, würde ich einen Bug auf CDT öffnen.


----------



## sirbender (29. Jan 2010)

Hier ist der gesamte Stack falls das hilft. Es ist eine Erweiterung zu CDT. Man legt ein neues Remote Project an und klickt auf Ok. Der Stack wird danach, also waehrend das neue Project angelegt wird geworfen.

Ist das eine Regel oder Konvention dass Builder nicht auf dem main thread laufen duerfen?


com.remoteproj.rm.remotetools.internal.ssh.FileTools.getOutputStream(FileTools.java:331)
com.remoteproj.rm.remote.remotetools.core.RemoteToolsFileStore.openOutputStream(RemoteToolsFileStore.java:365)
org.eclipse.core.internal.localstore.FileSystemResourceManager.write(FileSystemResourceManager.java:962)
org.eclipse.core.internal.localstore.FileSystemResourceManager.internalWrite(FileSystemResourceManager.java:539)
org.eclipse.core.internal.resources.Project.writeDescription(Project.java:1196)
org.eclipse.core.internal.resources.Project.setDescription(Project.java:1085)
org.eclipse.core.internal.resources.Project.setDescription(Project.java:1109)
org.eclipse.cdt.make.internal.core.BuildInfoFactory$BuildInfoProject.putString(BuildInfoFactory.java:490)
org.eclipse.cdt.make.internal.core.BuildInfoFactory$AbstractBuildInfo.setBuildAttribute(BuildInfoFactory.java:99)
com.remoteproj.rm.rdt.core.resources.RemoteMakeNature.configure(RemoteMakeNature.java:183)
org.eclipse.core.internal.resources.NatureManager$1.run(NatureManager.java:143)
org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
org.eclipse.core.internal.resources.NatureManager.configureNature(NatureManager.java:158)
org.eclipse.core.internal.resources.NatureManager.configureNatures(NatureManager.java:203)
org.eclipse.core.internal.resources.Project.basicSetDescription(Project.java:86)
org.eclipse.core.internal.resources.Project.setDescription(Project.java:1081)
org.eclipse.core.internal.resources.Project.setDescription(Project.java:1109)
com.remoteproj.rm.rdt.core.resources.RemoteMakeNature.addNature(RemoteMakeNature.java:59)
com.remoteproj.rm.rdt.ui.wizards.RemoteMakefileWizardHandler.createProject(RemoteMakefileWizardHandler.java:108)
org.eclipse.cdt.ui.wizards.CDTCommonProjectWizard$1$1$1.run(CDTCommonProjectWizard.java:257)
org.eclipse.ui.actions.WorkspaceModifyDelegatingOperation.execute(WorkspaceModifyDelegatingOperation.java:69)
org.eclipse.ui.actions.WorkspaceModifyOperation$1.run(WorkspaceModifyOperation.java:106)
org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1857)
org.eclipse.ui.actions.WorkspaceModifyOperation.run(WorkspaceModifyOperation.java:118)
org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:464)
org.eclipse.jface.operation.ModalContext.run(ModalContext.java:372)
org.eclipse.jface.wizard.WizardDialog.run(WizardDialog.java:946)
org.eclipse.cdt.ui.wizards.CDTCommonProjectWizard$1$1.run(CDTCommonProjectWizard.java:266)
org.eclipse.ui.internal.UILockListener.doPendingWork(UILockListener.java:155)
org.eclipse.ui.internal.UISynchronizer$3.run(UISynchronizer.java:158)
org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3487)
org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3134)
org.eclipse.jface.operation.ModalContext$ModalContextThread.block(ModalContext.java:173)
org.eclipse.jface.operation.ModalContext.run(ModalContext.java:388)
org.eclipse.jface.wizard.WizardDialog.run(WizardDialog.java:946)
org.eclipse.cdt.ui.wizards.CDTCommonProjectWizard.invokeRunnable(CDTCommonProjectWizard.java:179)
org.eclipse.cdt.ui.wizards.CDTCommonProjectWizard.getProject(CDTCommonProjectWizard.java:157)
org.eclipse.cdt.ui.wizards.CDTCommonProjectWizard.performFinish(CDTCommonProjectWizard.java:195)


----------



## Wildcard (29. Jan 2010)

> Ist das eine Regel oder Konvention dass Builder nicht auf dem main thread laufen duerfen?


Builder können long running sein. Long Running Operations werden allerdings grundsätzlich nicht im Dispatcher Thread ausgeführt, da solange die Oberfläche blockiert (wie du ja siehst). Also finde heraus was die Aktion genau triggert und sorg dafür das sie stattdessen in einem Job ausgeführt wird.


----------



## sirbender (30. Jan 2010)

Danke. Ich kann ja davon ausgehen, dass der Builder auch im main thread ablaeuft, wenn der Code danach im main thread ist, da alle Elemente in einem Stacktrace auch im selben thread ablaufen, oder?

Oder koennte der builder auch in einem anderen als dem main thread ablaufen und der Stack zeigt ihn trotzdem an?


----------



## Wildcard (30. Jan 2010)

> Danke. Ich kann ja davon ausgehen, dass der Builder auch im main thread ablaeuft, wenn der Code danach im main thread ist, da alle Elemente in einem Stacktrace auch im selben thread ablaufen, oder?


Richtig


----------

