none
Асинхронный запуск метода и получения ответа через callBack net fraemwork 2.x RRS feed

  • Вопрос

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

    Есть код -

            public override void Open(string param)
            {
                SaveToLog(0, "Open");
                //throw new NotImplementedException();
            }
            public override string Method(string param)
            {
                //SaveToLog(0, param);
                string str = null;
                try
                {
                    str = SendExternalRequest(param);
                }
                catch (Exception)
                {
                }
                //throw new NotImplementedException();
                return str;
            }
            public static void SaveToLog(int type, string message)
            {
                var messagetype = "";
                if (type == 0)
                {
                    messagetype = "Info ";
                }
                if (type == 1)
                {
                    messagetype = "Error";
                }
                var writer = new StreamWriter(@"C:\Terminal\Logic\Print.log", true);
                writer.WriteLine("[" + DateTime.Now + " : " + messagetype + "] " + message);
                writer.Close();
            }

    Мне необходимо вызвать метод суперкласса SendExternalRequest() в асинхронно (этот метод возвращает строку), и получить возвращаемое значение через callBack, на других профильных форумах не смогли подсказать, так как сделать это нужно под fraemwork 2.x

    Пробовал вот так, но тут 1) не асинхронно, и в итоге интерфейс виснет и не понятно как получить значение которое возвращает метод.

    public string answer;
            private delegate void MyReportDelegate(string param);
            public override void Open(string param)
            {
                SaveToLog(0, "Open");
                //throw new NotImplementedException();
            }
            public void sendQuery(string param)
            {
                string str = null;
                str = SendExternalRequest(param);
            }
            public override string Method(string param)
            {
                /*
                SaveToLog(0, param);
                string str = null;
                try
                {
                    str = SendExternalRequest(param);
                }
                catch (Exception)
                {
                }
                //throw new NotImplementedException();
                return str;
                object state;
                 * */
                MyReportDelegate _invoke = sendQuery;
                IAsyncResult _invokeResult = _invoke.BeginInvoke(param, MyReportCompleted, this);
                _invoke.EndInvoke(_invokeResult);
                return answer;
            }
            public void MyReportCompleted(object state)
            {
                
            }

    2 июля 2013 г. 10:59

Ответы

  • Да, я понимаю, но решение мало кому поможет, так как все дело было именно в ядре которое позволяло использовать методы .net во flash-e, в итоге я просто запустил метод в отдельном потоке, а вернул через "особый" метод ядра.

    • Помечено в качестве ответа YatajgaEditor 4 июля 2013 г. 6:57

Все ответы

  • По поводу APM, вам нужно передать метод обратного вызова с параметром IAsyncResult. Примерно так это будет для вашего случая:

     public class Test
      {
        public string answer;
        private delegate void MyReportDelegate(string param);
        public void Open(string param)
        {
          //SaveToLog(0, "Open");
          //throw new NotImplementedException();
        }
        public void sendQuery(string param)
        {
          string str = null;
          System.Threading.Thread.Sleep(1000);
          //str = SendExternalRequest(param);
        }
        public string Method(string param)
        {
          MyReportDelegate invoke = sendQuery;
          invoke.BeginInvoke(param, MyReportCompleted, this);
          return answer;
        }
        public void MyReportCompleted(IAsyncResult result)
        {
          Test t = result.AsyncState as Test;
        }
      }

    А чтобы UI поток не зависал надо использовать SynchronizationContext. Какое у вас приложение WPF или WinForms?


    Сделаем содержимое сообщества лучше, вместе!


    • Изменено YatajgaEditor 2 июля 2013 г. 11:39 Опечатки
    2 июля 2013 г. 11:36
    Модератор
  • Боюс мое приложение вообще сделано во flash-e, просто из него я могу дергать метод Method() из библиотеки на C#, а вернуть мне надо именно результат метода SendExternalRequest(param), т.е. то, что Вы законментировали.

    str = SendExternalRequest(param);

    надеюсь на Вашу помощь.

    Заранее Спасибо!


    2 июля 2013 г. 11:59
  • Так, немного проясните ситуации. Где и как должен выполняться ваш .NET - товский код, на сервере?

    Сделаем содержимое сообщества лучше, вместе!

    2 июля 2013 г. 12:04
    Модератор
  • Попробую обьяснить, но не уверен что получится, так как глубоко в эти .net-овские библиотеки я не лазил да и залезть не могу.

    Есть dll-ка, в которой описан метод SendExternalRequest, который передает запрос (в виде строки в шлюз), вызывать его на прямую из своего flash приложения я не могу, но могу написать свою библиотеку с подклассом от класса основной библиотеки, что я и сделал, из flash приложения мне в библиотеки доступен только метод Method(). Он корректно отрабатывает, но поблема в том, что во время отправки запроса, до получения ответа (от этого метода) интерфейс приложения на flash-е виснет. Так как action script не умеет запусть функции в отдельных потоках, то единственным выходом я вижу умудриться имея доступ только к методам Open() и Method() в библиотеки (а уж из них я могу делать что угодно) запустить SendExternalRequest асинхронно, но при этом как-то получить значение назад в переменную. (возможно из flash-а) есть доступ к callBack-у доступных методов библиотеки ( но этого я проверить не могу, так как не могу даже написать рабочий асинхронный запуск.

    Очень надюсь что описал более менее понятно =)

    2 июля 2013 г. 12:15
  • В целом всё понятно, вот только сам процесс взаимодействия не понятен. Как называется та технология, посредством которого ваш код из action script вызывает .net нетовский код, ваше приложение работает в браузере?. Дело в том, что для этого (реализации асинхронности) нужна .net исполняющая среда которая сама распределяет работу между потоками. Другая проблема, как уже описали вы, это механизм передачи данных обратно flash. В .NET это делается вызовом метода обратного вызова из вторичного потока. Нечто подобное долже быть тут, скорее всего. Например в Silverlight всё уже заранее настроено на асинхронность.

    Сделаем содержимое сообщества лучше, вместе!

    2 июля 2013 г. 12:46
    Модератор
  • К сожалению, технология взаимодействия между .net и flash-ом мне не известна, но есть уже реализованные библиотеки с асинхронным запуском методов (к сожалению их код я не могу получить), и данные возвращаются так же через callback, но проверить, есть ли у меня доступ к методу обратного вызова из своей библиотеки "обертки" я не могу, так как не могу даже написать такой рабочий метод =(

    Вот пример вызова callback-а из другой библиотеки внутри кода as

    К сожалению тут нету тего для вставки кода ас, так что вставлю просто так (эта обертка в AS 2.0), возможно она сможет чем-то помочь, заранее спасибо!

    // Получения данных из метода обратного вызова.

    DataReceived = function (data) {

    trace(data);

    }

    // Обработчик события обратного вызова.

    public function set DataReceived(f:Function)
     {
      this._DataReceived=f;
     }
     public function get DataReceived():Function
     {
      return this._DataReceived;
     }

    2 июля 2013 г. 12:57
  • "но есть уже реализованные библиотеки с асинхронным запуском методов" - можете назвать какие, попробую покапаться в их коде, если получится. Код который показал я в .Net будет работать асинхронно, нужно только расскоментировать метод ваш, я его закоментировал поскольку у меня он был неопределён. А результат возвращался в метод MyReportCompleted(IAsyncResult result).

    Сделаем содержимое сообщества лучше, вместе!

    2 июля 2013 г. 13:18
    Модератор
  • С удовольствем бы назвал, но они все "закрытые". Немного разузнал как они сделаны, попробую описать.

    Есть метод который вызывается из flash-а, после его запуска надо освободить поток ( что бы flash не зависал), а далее через уже описанный метод супер класса

    protected void CallBack(string nameFunction, object arg)

    вернуть результат во флеш, стандартный код библиотеки и последний комментарий, можете подсказать как это реализовать?

    public override void Open(string param)
            {
                SaveToLog(0, "Open");
                //throw new NotImplementedException();
            }
            public override string Method(string param)
            {
                SaveToLog(0, param);
                string str = null;
                try
                {
                    str = SendExternalRequest(param);
                }
                catch (Exception)
                {
                }
                //throw new NotImplementedException();
                return str;
      
            }
            public override void Close(string param)
            {
                //throw new NotImplementedException();
            }

    Заранее спасибо!
    2 июля 2013 г. 13:35
  • Всем спасибо, разобрался =)

  • Неплохо будет поделиться решением, оно может пригодиться другим в будущем.

    Сделаем содержимое сообщества лучше, вместе!

    Модератор
  • Да, я понимаю, но решение мало кому поможет, так как все дело было именно в ядре которое позволяло использовать методы .net во flash-e, в итоге я просто запустил метод в отдельном потоке, а вернул через "особый" метод ядра.

    • Помечено в качестве ответа YatajgaEditor 4 июля 2013 г. 6:57