Не могу дождаться прозрачного прокси в ожидании неблокирования ThreadPool - PullRequest
1 голос
/ 26 июня 2019

Могу ли я как-то зарегистрировать неблокирующий обработчик для маршаллированного сигнала в другом домене приложения?

У меня есть класс, который не может быть MarhsalByRef, но мне нужно иметь возможность вызывать метод A нав другом домене приложения D, а затем метод B в том же домене приложения D. Это может быть легко решено с помощью MarshalByRef - но я не могу использовать его из-за другого кода.

Поэтому я использую простое маршализуемое событие исигнал в другой домен приложения.Я хотел бы зарегистрировать неблокирующий обработчик в другом домене приложения - но это не представляется возможным.Я остался с активным ожиданием?

Ниже приведено repro:

    [Serializable]
    //this cannot be MarshalByRefObject
    public class AppDomainTest
    {
        private readonly ManualResetEvent _mrse = new ManualResetEvent(false);

        public static void Test()
        {
            AppDomainTest ap = new AppDomainTest();
            Task.Factory.StartNew(() => ap.CreateDomainAndRun());
            Thread.Sleep(1000);
            ap.CallIntoDomain();
        }

        public void CreateDomainAndRun()
        {
            var otherDomain = AppDomain.CreateDomain("MyDomain", AppDomain.CurrentDomain.Evidence);

            Task.Run(() => otherDomain.DoCallBack(RunInternal));
        }

        public void CallIntoDomain()
        {
            this._mrse.Set();
        }

        private void RunInternal()
        {
            //----------- HERE IS THE REPRO ---------------- //
            //This crashes
            //"Cannot wait on a transparent proxy"
            //ThreadPool.RegisterWaitForSingleObject(_mrse, CancellationCallBack, null,
            //    Timeout.InfiniteTimeSpan, true);

            Task.Factory.StartNew(() =>
            {
                //This works just fine
                _mrse.WaitOne();
                CallIntoDomainInternal();
            }, TaskCreationOptions.LongRunning).Wait();
        }

        private void CancellationCallBack(object state, bool timedOut)
        {
            CallIntoDomainInternal();
        }

        private void CallIntoDomainInternal()
        {
            Console.WriteLine($"App domain: {AppDomain.CurrentDomain.FriendlyName}");
        }
    }

Регистрация обратного вызова с помощью ThreadPool, генерирующими сообщения «Не удается дождаться прозрачного прокси».Активное ожидание в задании работает просто отлично.

...