Faking synchronous calls in Silverlight WP7

I'm porting some code from the full .NET framework to the WP7 version and I'm running into an issue with synchronous vs async calls.

 string response;
 string requestString = GenerateReqString();
 HttpWebRequest req = (HttpWebRequest) WebRequest.Create("endpoint");
 req.Method = "POST";
 req.ContentType = "text/xml";

 req.ContentLength = requestString.Length;

 StreamWriter sw = new StreamWriter (req.GetRequestStream(), System.Text.Encoding.ASCII);
 sw.Write(requestString);
 sw.Close();

 StreamReader sr = new StreamReader(req.GetResponse().GetResponseStream());
 response = sr.ReadToEnd();
 sr.Close();

The response string is then parsed into a list of objects that is returned by the method.

The problem I'm having is that there isn't a way to make the call synchronously in Silverlight/WP7. If I use a call back I'll get the response in a different function and wont be able to return it from the original function. Is there a way to either make the call synchronously or return from the CallBack function back to the method that kicked off the async call?

8
задан CACuzcatlan 16 August 2010 в 22:18
поделиться

2 ответа

Вам нужно иначе взглянуть на проблему. Чтобы асинхронные вещи «казались» синхронными, самый простой способ сделать это - реструктурировать код, чтобы использовать « стиль передачи продолжения ».

По сути, вместо вызова функции, которая возвращает значение, а затем вы обрабатываете это значение, вы вызываете функцию, передавая ей анонимную функцию в качестве делегата. Вызываемая функция затем вызовет делегата, передав строку.

Вот пример, в котором используются анонимные функции и лямбда-выражения:

void DoSomethingAsync( Action<string> callback ) {
    HttpWebRequest req; // TODO: build your request

    req.BeginGetResponse( result => {
        // This anonymous function is a closure and has access 
        // to the containing (or enclosing) function.
        var response = req.EndGetResponse( result );

        // Get the result string and call the callback
        string resultString = null; // TODO: read from the stream

        callback(resultString);
    }, null );
}

Это половина решения. Следующая часть - это на самом деле назвать это. Представьте, что у вас есть экземпляр ICommand или проще, событие нажатия кнопки, которое необходимо для вызова этой функции и «получения строки». Вместо «получения строки» вы вызываете эту функцию и предоставляете метод обратного вызова (который будет закрытием).

void btnGo_Click( object sender, EventArgs e ) {
    DoSomethingAsync( resultString => {
        // This anonymous function is called when the web request has
        // finished and has your string. 

        // Now that we have the string, we can go and process it.
        ProcessWebResponseResult( resultString );
    });
}

Вот действительно хорошая статья, объясняющая эту концепцию дальше: http://blogs.msdn.com/b/wesdyer/archive/2007/12/22/continuation-passing-style.aspx

11
ответ дан 5 December 2019 в 13:59
поделиться

Ознакомьтесь с библиотекой Wintellect Power Threading, которая позволяет выполнять асинхронные операции с моделью синхронного программирования.

http://csharperimage.jeremylikness.com/2010/03/sequential-asynchronous-workflows-in.html

1
ответ дан 5 December 2019 в 13:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: