Тупик - Windows Phone 8 BeginGetResponse c #

В моем потоке пользовательского интерфейса запущены два процесса. Однако, когда я запускаю первый, с функциональностью BeginGetStream, он входит в цикл и ожидает его выполнения и возвращает результат, когда вы будете готовы, но во втором прогоне, через функциональность BeginGetResponse, этот «умирает» там, и программа выполняет не продолжать и не возвращает мне нужное значение. В этих процессах используйте IasynResult.

Я пробовал:

  • Преобразовать в задачу (Task.Run)

  • Назначьте процессу новый поток (Thread x = new Thread ())

  • Установите параметр ConfigureAwait (ConfigureAwait (continueOnCapturedContext: false), ConfigureAwait (false));

  • Преобразуйте в методы asyncronos и примените "ожидание"

  • Используйте AutoResetEvent, чтобы дождаться завершения процесса и не продолжать.

  • Размещение потока в спящем режиме (Thread.Sleep)

  • Использование Thread.Start, Thread.Join

  • и т.д....

По сути, у меня есть три функции (Function1, Function2 и Function3). Изначально я использую только Function2 и function3, и все в порядке. Затем, в следующем порядке, где мне не нужна блокировка потока пользовательского интерфейса, он блокирует, и на этот раз блокирует три функции, которые у меня есть, но приложение блокирует меня, когда я делаю запрос на BeginGetResponse в Function2, а не там. (Перевод всего проекта в асинхронный режим очень дорого обходится, поэтому этот вариант будет последним.) Я не знаю, что еще можно сделать ... :( Пример кода:


Функция 1:

public void Function1()
             {

                  {           
HttpWebRequest requestHttp = (HttpWebRequest)HttpWebRequest.CreateHttp(new Uri(serverUrl, UriKind.Absolute));

                        string RString = string.Format("rftoken=123456789");
                        AutoResetEvent handler = new AutoResetEvent(false);
                        IAsyncResult TestResult= null;
                        try
                        {
                            requestHttp.BeginGetRequestStream(
                                (IAsyncResult result) =>
                                {
                                    TestResult= result;
                                    handler.Set();
                                }, requestHttp );

                            handler.WaitOne();

                        }
                        catch (Exception) { }

                        return Function2(TestResult, RString );
                    }               
                }

-------- ФУНКЦИЯ 2 ---------------------------------------- ------------------------------------------------

private Example Function2(IAsyncResult TestResult2, string RString2)

    try
    {
        HttpWebRequest request = (HttpWebRequest)TestResult2.AsyncState;
        Stream strm = request.EndGetRequestStream(TestResult2);
        StreamWriter writer = new StreamWriter(strm);
        writer.Write(RString2);
        writer.Dispose();
    }
    catch
    {}

    AutoResetEvent handler = new AutoResetEvent(false);
    IAsyncResult Async= null;

    try
    {
        requestHttp.BeginGetRequestStream(
            (IAsyncResult result) =>
            {
                Async= result;
                handler.Set();
            }, requestHttp );

        handler.WaitOne();

    }
    catch (Exception) { }

    return Function3(Async);
} 
}

------------ ФУНКЦИЯ 3 ------------------------------------ -------------------------------------------------- -

   private Example Function3 (IAsyncResult Async3)

{....}

... Не знаю, что еще попробовать ... Кто-нибудь может мне помочь.

Спасибо.


person fipcurren88    schedule 15.04.2015    source источник
comment
Вы не должны создавать IAsyncResult вручную, вы должны распространять сгенерированные с помощью функций Begin 'End'. Кроме того, если вы выполняете handler.WaitOne (), почему вы используете асинхронные функции? вы блокируете эти потоки ...   -  person Gusman    schedule 15.04.2015
comment
Привет спасибо. Поскольку мне нужен результат Function2 для вызова Function3 с правильным аргументом, в противном случае значение, переданное параметром, равно null, а нужная мне функциональность не выполняется в функции 3.   -  person fipcurren88    schedule 16.04.2015
comment
Нет, вы меня не поняли, я имею в виду, зачем использовать асинхронные методы, когда вы выполняете их синхронно? Вместо того, чтобы запускать запрос в функции, заблокируйте эту функцию и завершите загрузку в другой функции, просто выполняйте процесс синхронно и изолированно для каждой функции.   -  person Gusman    schedule 16.04.2015
comment
Здравствуйте, я попытался объединить функцию 1 и функцию в одной функции, но проблема не исчезла. Не понимаю, почему так происходит. Это вызывается через некоторое время, через 5 минут после запуска программы. Я просто не понимаю, зачем меня блокировать в Function2, когда я делаю второй вызов. Это потому, что Funtion2 и function3 вызываются для запуска приложения, и все в порядке. Во второй раз, когда я вызываю Function1, Function2 и Funtion 3, застрял в Function2. Я не понимаю в чем проблема. -- Спасибо   -  person fipcurren88    schedule 16.04.2015
comment
Как я сказал в своем ответе, вы не можете дважды вызвать BeginGetRequestStream, поэтому обработчик никогда не устанавливается, поэтому приложение застревает   -  person Gusman    schedule 16.04.2015


Ответы (2)


Я думаю, что ваш поток пользовательского интерфейса блокируется, потому что вы вызываете handler.WaitOne(); в синхронном методе Function1 в потоке пользовательского интерфейса.

Я думаю, что решение состоит в том, чтобы сделать все три метода асинхронными функциями, а также заставить метод вызывать вашу функцию1 для асинхронного метода.

Я предполагаю, что вы вызываете Function1 в событии щелчка и обновляете пользовательский интерфейс после получения результата. Тогда решение будет выглядеть так:

Тема пользовательского интерфейса

async void Click(object sender, RoutedEventArgs e)
{
        var result = await Function1();
}

Функция1, Функция2, Функция3

async Task<Result> Function1()
{
    var resp = await requestHttp.BeginGetRequestStream();
    return Function2(resp);
}

async Task<Result> Function2(Response response)
{
    var resp2 = await xxxxx();
    return Function3(resp2);
}

async Task<Result> Function(Type2 response)
{
    await xxxxx();
    //calculation
    return Result;
}
person 2power10    schedule 16.04.2015
comment
Привет, нет, я не вызываю функцию Function1 в событии щелчка. Существует широкий спектр функций, которые вызываются перед этим, однако проблема в том, что когда я делаю BeginGetResponse в Function2. Это вызывается через некоторое время, через 5 минут после запуска программы. Я просто не понимаю, зачем меня блокировать в Function2, когда я делаю второй вызов. Это потому, что Funtion2 и function3 вызываются для запуска приложения, и все в порядке. Во второй раз, когда я вызываю Function1, Function2 и Funtion 3, застрял в Function2. Я не понимаю в чем проблема. -- Спасибо - person fipcurren88; 16.04.2015

Хорошо, я понимаю, что вы используете платформу Silverlight, в которой есть только асинхронные методы.

Вы используете их неправильно, ваш код не должен блокироваться, вы должны «позволить асинхронному потоку»;)

void DownloadUrl()
{
    HttpWebRequest requestHttp = (HttpWebRequest)HttpWebRequest.CreateHttp(new Uri(serverUrl, UriKind.Absolute));

    requestHttp.BeginGetRequestStream(SendRequestContent, requestHttp);
}

void SendRequestContent(IAsyncResult Result)
{
    string RString = string.Format("rftoken=123456789");
    HttpWebRequest req = (HttpWebRequest)Result.AsyncState;
    var reqStream = req.EndGetRequestStream(Result);
    using(StreamWriter writer = new StreamWriter(reqStream))
        writer.Write(RString);

    //And here you have again GetRequestStream, I suppose it's wrong and you want ResponseStream, you cannot instantiate twice the request stream...

    req.BeginGetResponse(GetResponse, req);
}

void GetResponse(IAsyncResult Result)
{

    var req = (HttpWebRequest)Result.AsyncState;

    var response = (HttpWebResponse)req.EndGetResponse(Result);

    string content = null;

    using(StreamWriter sw = new StreamWriter(response.GetResponseStream())
        content = sw.ReadToEnd();

    //And now you have the HTTP response in the "content" string, you can now finally use it. Beware you are outside the UI thread, if you must interact with it remember to use Invoke()
}
person Gusman    schedule 16.04.2015