Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Асинхронный вызов


Автор: LarryBoss 23.12.2012, 21:49
Писал клиент-серверное приложение и в какой-то момент мне захотелось несколько переделать клиента, заменив в нем обычные вызовы веб сервисов на асинхронные и тут столкнулся с проблемой. Вот код который воссоздает мою проблему.

Это asmx веб сервис, тип проекта "Empty web aplication"
Код

    public class TestService : System.Web.Services.WebService
    {

        [WebMethod]
        public string HelloWorld()
        {
//слип для того что-бы клиент успел наверняка успеть отправить  запрос второму методу до того как вернется результат с первого
            Thread.Sleep(50); 
            return "Hello World";
        }

        [WebMethod]
        public string HelloDisney()
        {
            Thread.Sleep(50);
            return "Hello Disney";
        }
    }

Клиент, простое консольное приложение.
Код

        static void Main(string[] args)
        {
            localhost.TestService servise = new localhost.TestService();

            servise.HelloWorldCompleted += HelloBack;
            servise.HelloDisneyCompleted += DisneyBack;

            servise.HelloWorldAsync();
            servise.HelloDisneyAsync();

            Thread.Sleep(20000);

            Console.ReadKey();
        }

        private static void HelloBack(object sender, localhost.HelloWorldCompletedEventArgs e)
        {
            Console.WriteLine(e.Result);
        }

        private static void DisneyBack(object sender, localhost.HelloDisneyCompletedEventArgs e)
        {
            Console.WriteLine(e.Result);
        }
    }


И так по сути вопроса в клиентском коде выше так так он есть сейчас летит ошибка в обработчике события. Причем ошибка летит в случае если вызывается два асинхронных метода. А вот и в таком виде код уже отрабатывает нормально.
Код

    class Program
    {
        static void Main(string[] args)
        {
            localhost.TestService servise = new localhost.TestService();

            //создаем еще один прокси
            localhost.TestService servise2 = new localhost.TestService();

            servise.HelloWorldCompleted += HelloBack;
            servise2.HelloDisneyCompleted += DisneyBack;//используем service2

            servise.HelloWorldAsync();
            servise2.HelloDisneyAsync();//вызываем из service2

            Thread.Sleep(20000);

            Console.ReadKey();
        }

        private static void HelloBack(object sender, localhost.HelloWorldCompletedEventArgs e)
        {
            Console.WriteLine(e.Result);
        }

        private static void DisneyBack(object sender, localhost.HelloDisneyCompletedEventArgs e)
        {
            Console.WriteLine(e.Result);
        }
    }


Собственно мое негодование заключается в том что под каждый асинхронный вызов приходится создавать по экземпляру прокси класса. А что если бы у меня было 50 асинхронных вызовов? Понятно что от 50 вызовов методов никуда не деться, но вот создавать для этого 50 объектов это уже как-то странно для меня... Можно ли это как-то обойти? Я что-то не доделал или такое поведение задумано специально? И если да то зачем?

Автор: LarryBoss 23.12.2012, 23:23
Почему происходит ошибка уже вроде разобрался, обработчики событий и метод Main находятся в разных потоках, и когда срабатывает второй обработчик он не может что-то там сделать (получить доступ к основному потоку?) так как первым потоком уже сработала блокирока.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)