BackgroundWorker не вызывается - PullRequest
       1

BackgroundWorker не вызывается

2 голосов
/ 02 ноября 2010

Я пытаюсь предварительно загрузить сборки в фоновом потоке, и кажется, что когда вызывается функция PreLoadAssemblies, ничего не происходит и, как поток мертв или что-то еще (но я вижу поток в списке потоков).Когда я запускаю код в однопоточной среде, он работает нормально.

Здесь я создаю фоновый вызов:

 BackgroundWorker backgroundWorker = new BackgroundWorker();
 //[Threaded]
 private void InitlaizePoint()
 {
     backgroundWorker.DoWork += new DoWorkEventHandler(BackgroundInitalization);
     backgroundWorker.RunWorkerAsync();          
 }

Вот функция фоновой инициализации.Он останавливается (имеется в виду, что ничего не происходит, и я вижу, что мой индикатор выполнения диалогового окна работает «на пустом») после того, как я пытаюсь выполнить пошаговое выполнение PReLoadAssemblies.1009 *

private static void PreLoadAssemblies()
{
    //statusController.PublishStatus("pre-loading assemblies");
    var missingAssemblies = new ArrayList();
    var loadedAssemblies = new ArrayList();
    LoadDependencies(Assembly.GetExecutingAssembly().GetName(), missingAssemblies, loadedAssemblies);
}

private static void LoadDependencies(AssemblyName name, ArrayList missingAssemblies, ArrayList loadedAssemblies)
{
    try
    {
        //statusController.PublishStatus("Loading dependencies");

        Assembly a = Assembly.Load(name);
        loadedAssemblies.Add(name.FullName);
        foreach (AssemblyName depends in a.GetReferencedAssemblies())
        {
            if (!IsAssemblyLoaded(depends.FullName, loadedAssemblies))
                LoadDependencies(depends, missingAssemblies, loadedAssemblies);
        }
    }
    catch (Exception)
    {
        missingAssemblies.Add(name);
    }
}

private static bool IsAssemblyLoaded(String name, ArrayList preloadedAssemblies)
{
    if (preloadedAssemblies.IndexOf(name) == -1)
        return false;
    return true;
}

Дайте мне знать, если у вас есть идеи.

Спасибо

Ответы [ 3 ]

3 голосов
/ 02 ноября 2010

Где именно вы вызываете этот метод? Классу BackgroundWorker нужен уже работающий насос сообщений, и он не будет работать, если вы вызываете его слишком рано в приложении (до Application.Run ()).

Если вы делаете это с помощью чего-то вроде заставки, которая запускается до запуска основного приложения, к сожалению, вам придется выполнять собственные потоки вместо использования BackgroundWorker.

Примечание. Как отмечает Хенк Холтерман, если у вас вообще нет сообщения (потому что у вас консольное приложение вместо Winforms или WPF), то BackgroundWorker не будет работать вообще ваше приложение.

1 голос
/ 02 ноября 2010

Мы смотрим на отредактированную версию вашего кода.Вы удалили биты, которые вызывают тупик.Некоторые примечания:

  • Вы упомянули «индикатор выполнения статуса», но ваш код не подтверждает этого.Обновление этой панели предоставляет широкие возможности для взаимоблокировки.
  • Закомментированные вызовы PublishStatus имеют красный флаг
  • Нет никаких свидетельств того, что обработчик событий RunWorkerCompleted нужен, чтобы онзаставка закрыта.BGW блокируется, когда ваш основной поток блокирует BGW, а не перекачивает сообщения
  • Существует угловой случай для циклических зависимостей между сборками.Ваш код будет висеть в бесконечном цикле.Диагностика с помощью Build + Clean, Build + Build.
  • Удаленная, но несколько сборок .NET, а также сборки C ++ / CLI имеют инициализатор модуля.Это может не обязательно работать должным образом, когда сборка загружается в рабочий поток, не являющийся STA.

RunWorkerCompleted - мое лучшее предположение, пока вы не покажете неотредактированную версию своего кода.

0 голосов
/ 02 ноября 2010

Вы не можете предварительно загружать сборки так легко. Взгляните на мой вопрос .

...