none
Ошибка при обращении при запуске потока в разных доменах RRS feed

  • Вопрос

  • Добрый день!

    У меня такая проблема. Есть класс, который по ходу своей работы запускает различные потоки на выполнение. Мне необходимо в разных доменах использовать этот класс. Я в каждом домене создаю сборку, создаю экземпляр класса. В првом домене все делается нормально, а во втором домене как только дело доходит до запуска потока, выдается ошибка: "Поток выполняется или прерван; его нельзя запустить повторно." Как такое может быть, если они в разных доменах?

    Вот так я создаю домен:

    AppDomain app = AppDomain.CreateDomain("Exchange");
    Assembly exchageAssembly = app.Load(typeof(ExchangeConsole.ConsoleWrapper).Assembly.FullName);

    ExchangeConsole.ConsoleWrapper wrapper = (ExchangeConsole.ConsoleWrapper)exchageAssembly.CreateInstance("ExchangeConsole.ConsoleWrapper", true);

    wrapper.Start();    // Здесь вызывается поток

    //...
    wrapper.Stop();

    AppDomain.Unload(app);
    Thread.Sleep(10000);

    • Перемещено I.Vorontsov 10 июня 2010 г. 5:31 (От:Visual C#)
    • Перемещено Tagore Bandlamudi 2 октября 2010 г. 21:31 MSDN Forums consolidation (От:Разработка Windows-приложений)

Ответы

  • Дело скорей всего в том, как определен класс ExchangeConsole.ConsoleWrapper. Мало кода и конкретики. Может быть вы  забыли наследовать его от MarshalByRefObject или еще что-то. Максимум что могу сдедлать - привести код, в котором имеется класс, в нем определен метод, запускающий новый поток. Создается второй домен, в нем создается экземпляр этого класса и вызывается метод, запускающий поток. ВСё работает.

    namespace ConsoleApplication4
    {
      class Program
      {
        static void Main(string[] args)
        {
          AppDomain secondDomain = AppDomain.CreateDomain("TestDomain");
          TestClass test = (TestClass)secondDomain.CreateInstanceAndUnwrap("ConsoleApplication4", "ConsoleApplication4.TestClass");
          test.Start();
          AppDomain.Unload(secondDomain);
        }
      }
    
      public class TestClass : MarshalByRefObject
      {
        public void Start()
        {
          var th = new Thread(() =>
            {
              Console.WriteLine("Thread Start");
              Thread.Sleep(3000);
              Console.WriteLine("Thread End");
            });
          th.Start();
          th.Join();
        }
      }
    }
    • Помечено в качестве ответа Inf0man 9 июня 2010 г. 11:27

Все ответы

  • Дело скорей всего в том, как определен класс ExchangeConsole.ConsoleWrapper. Мало кода и конкретики. Может быть вы  забыли наследовать его от MarshalByRefObject или еще что-то. Максимум что могу сдедлать - привести код, в котором имеется класс, в нем определен метод, запускающий новый поток. Создается второй домен, в нем создается экземпляр этого класса и вызывается метод, запускающий поток. ВСё работает.

    namespace ConsoleApplication4
    {
      class Program
      {
        static void Main(string[] args)
        {
          AppDomain secondDomain = AppDomain.CreateDomain("TestDomain");
          TestClass test = (TestClass)secondDomain.CreateInstanceAndUnwrap("ConsoleApplication4", "ConsoleApplication4.TestClass");
          test.Start();
          AppDomain.Unload(secondDomain);
        }
      }
    
      public class TestClass : MarshalByRefObject
      {
        public void Start()
        {
          var th = new Thread(() =>
            {
              Console.WriteLine("Thread Start");
              Thread.Sleep(3000);
              Console.WriteLine("Thread End");
            });
          th.Start();
          th.Join();
        }
      }
    }
    • Помечено в качестве ответа Inf0man 9 июня 2010 г. 11:27
  • Огроменное спасибо!

    1) я унаследовал ExchangeConsole.ConsoleWrapper от MarshalByRefObject

    2) я создал экземпляр класса методом домена CreateInstanceAndUnwrap(), а не CreateInstance() сборки

    Все заработало!

    9 июня 2010 г. 11:27