2015-09-15 2 views
2

Я в настоящее время разрабатывает Затмения-RCP приложение, которое хранит для каждого проекта настройки с помощью EclipsePreference механизм через ProjectScope. Сначала это работало очень хорошо, но мы столкнулись с трудностями при доступе к этим предпочтениям (read-) в многопоточных сценариях, в то же время в рабочую область вносятся изменения. По-видимому, проблематично обращаться к этому предпочтительному узлу (ProjectScope.getNode()), в то время как проект удаляется асинхронным действием пользователя (щелкните правой кнопкой мыши Project -> Delete Project). В таких случаях мы получаем довольно смесьпоточно-способ доступа EclipsePreferences (проект)

  • org.osgi.service.prefs.BackingStoreException
  • java.io.FileNotFoundException
  • org.eclipse.core.runtime.CoreException

По существу все они жалуются, что основной файл больше не существует.

Первоначальные попытки исправить это с помощью чеков, как IProject.exists() или isAccessible() и даже так далеко, как проверка наличия файла фактических .prefs были тщетны, как и ожидалось: они только делают исключения менее вероятно, но на самом деле не мешает их.

Так что мой вопрос: как вы должны безопасно обращаться к вещам вроде ProjectScope.getNode()? Вам нужно зайти так далеко, чтобы каждый читать в WorkspaceJob или есть какой-то другой, умный способ предотвратить вышеупомянутые проблемы, такие как помещение доступа для чтения в Display.asyncExec()?

Хотя я и пытался, я действительно не нашел ответы на вышеупомянутый вопрос в документации Eclipse.

ответ

1

Обычно scheduling rules используются для одновременного доступа к ресурсам в рабочей области.

Я никогда не работал с настройками ed ProjectScope, но если они хранятся в проекте или его метаданных, тогда правило планирования должно помогать координировать доступ. Если вы работаете код доступа предпочтения в работе аппарата, а затем соответствующее правило планирования следует сделать:

Например:

IProject project = getProjectForPreferences(projectPreferences); 
ISchedulingRule rule = project.getWorkspace().getRuleFactory().modifyRule(project); 
Job job = new Job("Access Project Preferences") { 
    @Override 
    protected IStatus run(IProgressMonitor monitor) { 
    if(project.exists()) { 
     // read or write project preferences 
    } 
    return Status.OK_STATUS; 
    } 
}; 
job.setRule(rule); 
job.schedule(); 

Код приобретающего правило для изменения проекта и работы гарантированно запускается только тогда, когда не выполняется другая работа с правилом conflichting.

Если ваш код не работает в задании, вы также можете вручную получить блокировку с помощью IJobManager.beginRule() и endRule().

Например:

ISchedulingRule rule = ...; 
try { 
    jobManager.beginRule(rule, monitor); 
    if(project.exists()) { 
    // read or write project preferences 
    } 
} finally { 
    jobManager.endRule(rule); 
} 

Как неловко, как это выглядит, вызов beginRuleдолжен быть внутри блока попробовать, увидеть JavaDoc для более подробной информации.

+0

Благодарим за этот быстрый ответ. Такое решение было именно тем, что я имел в виду, и он отлично работает для API EclipsePreferences (он выжил в stresstest с использованием UI-автоматизации с QF-Test). – Ilmarinen123

Смежные вопросы