Резюме: это вообще возможно?
unit test function on ui thread:
- creates a background thread
- starts the thread
- waits for it to complete (function does not exit until it completes!)
background thread:
- opens an http stream
- reads a url from the web
- terminates
Мое подозрение: фреймворк асинхронно помещает результат в некоторую внутреннюю очередь сообщений, и поэтому ответный обратный вызов никогда не будет вызываться, пока стек потока пользовательского интерфейса не раскрутится и не перейдет к какой-либо функции потока пользовательского интерфейса для накачки стека.
Полная история:
Я портирую приложение, которое требует создания потока из различных источников, один из которых из простого http URL. Я делаю это в фоновом потоке, и в идеале я хотел бы, чтобы он вел себя на 100% синхронно, просто блокируйте при необходимости (это нормально, так как это в фоновом потоке).
Но кажется, что фреймворк немного микки-мышка в том смысле, что он предполагает, что вы будете выполнять запрос в потоке пользовательского интерфейса, и это защитит кодера от необходимости создавать фоновый поток для выполнения асинхронной операции. Но я могу что-то упустить.
Я наткнулся на следующую статью:
http://pieterderycke.wordpress.com/2011/05/23/adding-synchronous-methods-to-webrequest-on-windows-phone-7/,
который предлагает решение, чтобы сделать http веб-запрос синхронным. Но, как это реализовано, я получаю исключение ProtocolViolationException. С тех пор я сделал изменение в коде, чтобы использовать BeginGetResponse () вместо BeginGetRequestStream (), и это, похоже, больше не вызывает исключение.
Но похоже, что фоновый поток теперь блокируется на неопределенный срок. В моем потоке пользовательского интерфейса я зацикливаюсь, выполняя Thread.Sleep (10), поскольку я нахожусь в функции модульного теста, ожидая, когда будет вызван мой обратный вызов. Возможно ли, что обратный вызов не будет вызываться до тех пор, пока не вернется функция модульного теста и поток пользовательского интерфейса не сможет перекачать сообщения? Если это так, каким-либо образом я могу заставить его качать, чтобы я мог продолжить с того места, на котором остановился в процедуре модульного тестирования?
В нижней части упомянутой выше статьи делается комментарий: «Если вы протестируете свой код, вы обнаружите, что он блокируется, если вы выполняете его в потоке пользовательского интерфейса». но я выполняю его в фоновом потоке, так что должно быть в порядке, верно?
В документах msdn показано только, как выполнять асинхронные вызовы. И они также отмечают, что «метод BeginGetResponse требует выполнения некоторых задач синхронной настройки для« ... »обычно нескольких секунд» ... но «может занять 60 секунд или более». Это звучит довольно плохо, чтобы быть выполненным в пользовательском потоке.
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse.aspx
Пожалуйста, помогите!
Вот мой код:
using System.Net;
using System.Threading;
using System;
using System.IO;
namespace Blah
{
// http://pieterderycke.wordpress.com/2011/05/23/adding-synchronous-methods-to-webrequest-on-windows-phone-7/
// Creates synchronous web requests.
// Must not be called on UI threads.
public static class WebRequestExtensions
{
public static Stream GetRequestStream(this WebRequest request)
{
AutoResetEvent autoResetEvent = new AutoResetEvent(false);
IAsyncResult asyncResult = null;
{
// /178566/kak-ispolzovat-httpwebrequest-s-metodom-get
if (request.Method == "GET")
{
asyncResult = request.BeginGetResponse(
r => autoResetEvent.Set(), null);
}
else
{
asyncResult = request.BeginGetRequestStream(
r => autoResetEvent.Set(), null);
}
}
// Wait until the call is finished
autoResetEvent.WaitOne();
return request.EndGetRequestStream(asyncResult);
}
}
}
Я также недавно наткнулся на http://www.eggheadcafe.com/tutorials/aspnet/91f69224-3da5-4959-9901-c5c717c9b184/making-silverlight-emulate-synchronous-requests.aspx,, но это та же проблема. Кажется, я не получаю свой обратный вызов, пока поток пользовательского интерфейса не вернется в стек ... Я чувствую запах какой-то очереди сообщений фреймворка где-то там, я прав?
Спасибо