Работа с доменами.
От: Аноним  
Дата: 14.06.07 11:33
Оценка:
Привет всем!
Код у меня примерно такой:

public static class MyClass
{
   public static void Method1(bool flag)
   {
    if (flag) {
     //Надо запустить Method2 в том же потоке
    }
    else {
     //Надо запустить Method2 в отдельном домене
     AppDomainSetup ads = new AppDomainSetup();
     AppDomain ad2 = AppDomain.CreateDomain("New Domain", null, ads);
     Starter mbrt = 
                (Starter) ad2.CreateInstanceAndUnwrap(Assembly.GetEntryAssembly().FullName,
                                                               typeof(Starter).FullName);
     mbrt.Runner(objTClist);
    }
   }
   public static void Method2
   {
   }
}

class Starter : MarshalByRefObject
{
    public void Runner
    {
        MyClass.Method2();
    }
}


Получается, чтобы запустить метод 2 в отдельном домене я создаю доп. класс и вынужден сделать Method2 публичным. Как-то сильно некрасиво. Может подскажет кто, как это сделать лучше?
Re: Работа с доменами.
От: ksg71 Германия  
Дата: 14.06.07 13:09
Оценка:
Здравствуйте, Аноним, Вы писали:


А>Получается, чтобы запустить метод 2 в отдельном домене я создаю доп. класс и вынужден сделать Method2 публичным. Как-то сильно некрасиво. Может подскажет кто, как это сделать лучше?


вот так к примеру

class Program
    {
        static void Main(string[] args)
        {
            AppDomain another = AppDomain.CreateDomain("Another appDomain");
            another.DoCallBack(Hello);
        }

        static void Hello()
        {
            Console.WriteLine("Hello from " + AppDomain.CurrentDomain.FriendlyName);
        }
    }
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Re[2]: Работа с доменами.
От: gwen Украина  
Дата: 14.06.07 13:30
Оценка:
Здравствуйте, ksg71, Вы писали:

K>вот так к примеру


K>
K>class Program
K>    {
K>        static void Main(string[] args)
K>        {
K>            AppDomain another = AppDomain.CreateDomain("Another appDomain");
K>            another.DoCallBack(Hello);
K>        }

K>        static void Hello()
K>        {
K>            Console.WriteLine("Hello from " + AppDomain.CurrentDomain.FriendlyName);
K>        }
K>    }
K>


Спасибо. Невнимательно читал MSDN.
А чем такой вызов лучше или хуже описанного в MSDN:

public void DoCallBack (
    CrossAppDomainDelegate callBackDelegate
)


otherDomain.DoCallBack(new CrossAppDomainDelegate(MyCallBack));
Re[3]: Работа с доменами.
От: ksg71 Германия  
Дата: 14.06.07 13:39
Оценка: 2 (1)
Здравствуйте, gwen, Вы писали:

G>Здравствуйте, ksg71, Вы писали:


не понял, это в C# 2.0 можно писать


otherDomain.DoCallBack(new CrossAppDomainDelegate(MyCallBack));
otherDomain.DoCallBack(MyCallBack);
otherDomain.DoCallBack(delegate { /*.....*/ });
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Re[4]: Работа с доменами.
От: gwen Украина  
Дата: 14.06.07 14:48
Оценка:
Здравствуйте, ksg71, Вы писали:

K>Здравствуйте, gwen, Вы писали:


G>>Здравствуйте, ksg71, Вы писали:


K>не понял, это в C# 2.0 можно писать


K>

K>otherDomain.DoCallBack(new CrossAppDomainDelegate(MyCallBack));
K>otherDomain.DoCallBack(MyCallBack);
K>otherDomain.DoCallBack(delegate { /*.....*/ });

K>


В продолжение нашей дискуссии появляется еще один вопрос, а если метод MaCallBack с параметрами, да еще и статический, как его передавать? В MSDN указан только пример, когда метод вызывается без парамеров, а если надо передать параметры, то они передаются как поля экземпляра класса.
Re[5]: Работа с доменами.
От: gwen Украина  
Дата: 14.06.07 15:23
Оценка:
Здравствуйте, gwen, Вы писали:

G>Здравствуйте, ksg71, Вы писали:


K>>Здравствуйте, gwen, Вы писали:


G>>>Здравствуйте, ksg71, Вы писали:


K>>не понял, это в C# 2.0 можно писать


K>>

K>>otherDomain.DoCallBack(new CrossAppDomainDelegate(MyCallBack));
K>>otherDomain.DoCallBack(MyCallBack);
K>>otherDomain.DoCallBack(delegate { /*.....*/ });

K>>


G>В продолжение нашей дискуссии появляется еще один вопрос, а если метод MaCallBack с параметрами, да еще и статический, как его передавать? В MSDN указан только пример, когда метод вызывается без парамеров, а если надо передать параметры, то они передаются как поля экземпляра класса.


Кажется уже сам разобрался:

otherDomain.DoCallBack(delegate { MyCallBack(prm1, prm2, ... ); } );
Re[6]: Работа с доменами.
От: gwen Украина  
Дата: 14.06.07 17:25
Оценка:
При дальнейших исследованиях появилась еще одна загвоздка. При попытке сделать следующее:

AppDomainSetup ads = new AppDomainSetup();
AppDomain ad2 = AppDomain.CreateDomain("New Domain", null, ads);
ad2.DoCallBack(delegate {ExecuteTestCaseInThread(objTClist); } );


Вылетает эксцепшн:
Exception System.Runtime.Serialization.SerializationException was thrown in debuggee:
Type 'TCManagement.TestLoader.BHTestLoader+<>c__DisplayClass1' in assembly 'TCManagement, Version=1.0.2721.34564, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

Это при том, что у класса BHTestLoader есть атрибут [serializable]
Кто-нибудь может рассказать в чем дело?
Re[7]: Работа с доменами.
От: ksg71 Германия  
Дата: 15.06.07 06:32
Оценка:
Здравствуйте, gwen, Вы писали:

G>При дальнейших исследованиях появилась еще одна загвоздка. При попытке сделать следующее:


G>
G>AppDomainSetup ads = new AppDomainSetup();
G>AppDomain ad2 = AppDomain.CreateDomain("New Domain", null, ads);
G>ad2.DoCallBack(delegate {ExecuteTestCaseInThread(objTClist); } );
G>


G>Вылетает эксцепшн:

G>Exception System.Runtime.Serialization.SerializationException was thrown in debuggee:
G>Type 'TCManagement.TestLoader.BHTestLoader+<>c__DisplayClass1' in assembly 'TCManagement, Version=1.0.2721.34564, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

G>Это при том, что у класса BHTestLoader есть атрибут [serializable]

G>Кто-нибудь может рассказать в чем дело?

Ничего непонятно, какова цель?
Код в студию
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Re[8]: Работа с доменами.
От: gwen Украина  
Дата: 15.06.07 10:54
Оценка:
Здравствуйте, ksg71, Вы писали:

K>Здравствуйте, gwen, Вы писали:


G>>При дальнейших исследованиях появилась еще одна загвоздка. При попытке сделать следующее:


G>>
G>>AppDomainSetup ads = new AppDomainSetup();
G>>AppDomain ad2 = AppDomain.CreateDomain("New Domain", null, ads);
G>>ad2.DoCallBack(delegate {ExecuteTestCaseInThread(objTClist); } );
G>>


G>>Вылетает эксцепшн:

G>>Exception System.Runtime.Serialization.SerializationException was thrown in debuggee:
G>>Type 'TCManagement.TestLoader.BHTestLoader+<>c__DisplayClass1' in assembly 'TCManagement, Version=1.0.2721.34564, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

G>>Это при том, что у класса BHTestLoader есть атрибут [serializable]

G>>Кто-нибудь может рассказать в чем дело?

K>Ничего непонятно, какова цель?

K>Код в студию


[Serializable]
public static class BHTestLoader
{
    public static void ExecuteTC(object objTClist)
    {
        switch (options.RunningStyle) {
            case RunningStyles.SingleThread:
                bgThread = new Thread(new ParameterizedThreadStart(ExecuteTestCaseInThread));
                break;
            case RunningStyles.SingleDomain:
                bgThread = new Thread(new ParameterizedThreadStart(ExecuteTestCaseInDomain));
                break;
        }
        bgThread.Start(objTClist);
    }
    public static void ExecuteTestCaseInThread(object objTClist)
    {
        List<TestCase> TClist = new List<TestCase>();
        if (objTClist as List<TestCase> != null) {
            TClist = objTClist as List<TestCase>;
        }
        else {
            TestCase atc = objTClist as TestCase;
            TClist.Add(atc);
        }
        List<string> AssemblyPathList = new List<string>();
        foreach (TestCase tc in TClist) {
            if (!AssemblyPathList.Contains(tc.AssemblyPath)) {
                AssemblyPathList.Add(tc.AssemblyPath);
            }
        }
        
        FireExecuteStateChanged(ExecuteStates.Run);
        foreach (string path in AssemblyPathList) {
            List<TestCase> li = new List<TestCase>();
            foreach (TestCase tc in TClist) {
                if (tc.AssemblyPath == path) {
                    li.Add(tc);
                }
            }
            ExecuteTestMethods(li);
        }
    }
    private static void ExecuteTestCaseInDomain(object objTClist)
    {
        AppDomainSetup ads = new AppDomainSetup();
        AppDomain ad2 = AppDomain.CreateDomain("New Domain", null, ads);
        ad2.DoCallBack(delegate {ExecuteTestCaseInThread(objTClist); } );
         bgThread.Abort();
    }

}

В зависимости от настройки опций надо запустить метод ExecuteTestCaseInThread либо в отдельном потоке, либо в отдельном домене.
И вот при вызове

ad2.DoCallBack(delegate {ExecuteTestCaseInThread(objTClist); } );

Выскакивает вышеупомянутое исключение.
Re[9]: Работа с доменами.
От: ksg71 Германия  
Дата: 15.06.07 11:11
Оценка: 2 (1)
Здравствуйте, gwen, Вы писали:

G>Здравствуйте, ksg71, Вы писали:


K>>Здравствуйте, gwen, Вы писали:


G>>>При дальнейших исследованиях появилась еще одна загвоздка. При попытке сделать следующее:


G>>>
G>>>AppDomainSetup ads = new AppDomainSetup();
G>>>AppDomain ad2 = AppDomain.CreateDomain("New Domain", null, ads);
G>>>ad2.DoCallBack(delegate {ExecuteTestCaseInThread(objTClist); } );
G>>>


G>>>Вылетает эксцепшн:

G>>>Exception System.Runtime.Serialization.SerializationException was thrown in debuggee:
G>>>Type 'TCManagement.TestLoader.BHTestLoader+<>c__DisplayClass1' in assembly 'TCManagement, Version=1.0.2721.34564, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

G>>>Это при том, что у класса BHTestLoader есть атрибут [serializable]

G>>>Кто-нибудь может рассказать в чем дело?


Apply the SerializableAttribute attribute to a type to indicate that instances of this type can be serialized. The common language runtime throws SerializationException if any type in the graph of objects being serialized does not have the SerializableAttribute attribute applied.


а применение анонимного метода

ad2.DoCallBack(delegate {ExecuteTestCaseInThread(objTClist); } );


приводит к появлению в BHTestLoader сгенерированного компилятором члена типа CrossAppDomainDelegate, который не имеет
атрибута Serializable
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Re[10]: Работа с доменами.
От: gwen Украина  
Дата: 15.06.07 11:23
Оценка:
Здравствуйте, ksg71, Вы писали:


K>

K>Apply the SerializableAttribute attribute to a type to indicate that instances of this type can be serialized. The common language runtime throws SerializationException if any type in the graph of objects being serialized does not have the SerializableAttribute attribute applied.


K>а применение анонимного метода


K>
K>ad2.DoCallBack(delegate {ExecuteTestCaseInThread(objTClist); } );
K>


K>приводит к появлению в BHTestLoader сгенерированного компилятором члена типа CrossAppDomainDelegate, который не имеет

K>атрибута Serializable

Ясно. Спасибо. А есть идеи, как тут выкрутиться? Как я уже писал, не очень хочется специально создавать класс-наследник MarshalByRefObject для запуска ExecuteTestCaseInThread.
Re[10]: Работа с доменами.
От: ksg71 Германия  
Дата: 15.06.07 11:27
Оценка:
Здравствуйте, ksg71, Вы писали:

K>Здравствуйте, gwen, Вы писали:


G>>Здравствуйте, ksg71, Вы писали:


K>>>Здравствуйте, gwen, Вы писали:


G>>>>При дальнейших исследованиях появилась еще одна загвоздка. При попытке сделать следующее:


G>>>>
G>>>>AppDomainSetup ads = new AppDomainSetup();
G>>>>AppDomain ad2 = AppDomain.CreateDomain("New Domain", null, ads);
G>>>>ad2.DoCallBack(delegate {ExecuteTestCaseInThread(objTClist); } );
G>>>>


G>>>>Вылетает эксцепшн:

G>>>>Exception System.Runtime.Serialization.SerializationException was thrown in debuggee:
G>>>>Type 'TCManagement.TestLoader.BHTestLoader+<>c__DisplayClass1' in assembly 'TCManagement, Version=1.0.2721.34564, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

G>>>>Это при том, что у класса BHTestLoader есть атрибут [serializable]

G>>>>Кто-нибудь может рассказать в чем дело?


K>

K>Apply the SerializableAttribute attribute to a type to indicate that instances of this type can be serialized. The common language runtime throws SerializationException if any type in the graph of objects being serialized does not have the SerializableAttribute attribute applied.


K>а применение анонимного метода


K>
K>ad2.DoCallBack(delegate {ExecuteTestCaseInThread(objTClist); } );
K>


K>приводит к появлению в BHTestLoader сгенерированного компилятором члена типа CrossAppDomainDelegate, который не имеет

K>атрибута Serializable

малость соврал — компилятор создает класс (в данном случае 'TCManagement.TestLoader.BHTestLoader+<>c__DisplayClass1' )
для передачи локальной переменной в анонимный метод, естественно этот тип не сериализуем
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Re[11]: Работа с доменами.
От: ksg71 Германия  
Дата: 15.06.07 11:41
Оценка:
Здравствуйте, gwen, Вы писали:

G>Здравствуйте, ksg71, Вы писали:



K>>

K>>Apply the SerializableAttribute attribute to a type to indicate that instances of this type can be serialized. The common language runtime throws SerializationException if any type in the graph of objects being serialized does not have the SerializableAttribute attribute applied.


K>>а применение анонимного метода


K>>
K>>ad2.DoCallBack(delegate {ExecuteTestCaseInThread(objTClist); } );
K>>


K>>приводит к появлению в BHTestLoader сгенерированного компилятором члена типа CrossAppDomainDelegate, который не имеет

K>>атрибута Serializable

G>Ясно. Спасибо. А есть идеи, как тут выкрутиться? Как я уже писал, не очень хочется специально создавать класс-наследник MarshalByRefObject для запуска ExecuteTestCaseInThread.



можно еще попробовать передавать данные пользуясь

AppDomain.GetData
AppDomain.SetData

и использовать DoCallBack
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.