swi*_*ter 6 c# silverlight windows-phone-7
摘要:这甚至可能吗?
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
Run Code Online (Sandbox Code Playgroud)
我的怀疑:框架异步地将结果放到一些内部消息队列中,因此在ui线程的堆栈展开之前永远不会调用响应回调,并转到某个ui线程函数来抽取堆栈.
全文:
我正在移植一个应用程序,需要从各种来源创建一个流,其中一个来自一个简单的http网址.我在后台线程上这样做,理想情况下我希望它100%同步,只需要在需要时阻塞(这是好的,因为它在后台线程上).
但似乎框架有点米老鼠,因为它假定你将在ui线程上执行请求,因此它将保护编码器不必创建后台线程来执行异步操作.但我可能会遗漏一些东西.
我偶然发现了以下文章:http: //pieterderycke.wordpress.com/2011/05/23/adding-synchronous-methods-to-webrequest-on-windows-phone-7/,它提出了一个解决方案,使http web请求同步.但是当它实现时,我得到一个ProtocolViolationException.我已经对代码进行了修改以使用BeginGetResponse()而不是BeginGetRequestStream(),这似乎不再导致异常.
但似乎后台线程现在无限期地阻塞.在我的ui线程上,我循环,执行Thread.Sleep(10)因为我在单元测试函数中,等待我的回调被调用.是否有可能在单元测试函数返回并且ui线程有机会抽取消息之前不会调用回调?如果是这样,我可以用任何方式强制它进行泵送,以便我可以继续在单元测试程序中停止的地方?
在上面提到的文章的底部,发表评论"如果你测试你的代码,你会发现如果你在UI线程上执行它会死锁." 但是我在后台线程上执行它,所以应该没问题吧?
msdn文档只显示如何进行异步调用.他们还提到"BeginGetResponse方法需要一些同步设置任务才能完成"......"通常需要几秒钟"......但"可能需要60秒或更长时间".在ui线程上执行这听起来很糟糕. 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;
{
// http://stackoverflow.com/questions/253549/how-do-i-use-httpwebrequest-with-get-method
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我最近偶然发现了http://www.eggheadcafe.com/tutorials/aspnet/91f69224-3da5-4959-9901-c5c717c9b184/making-silverlight-emulate-synchronous-requests.aspx,但这也表现出同样的问题.似乎我没有得到我的回调,直到ui线程返回堆栈...我可以闻到某处的某种框架消息队列,我是否正确?
谢谢
由于 HTTP 响应处理使用 UI 线程,阻止它会阻止请求完成。
假设您正在使用 Silverlight 单元测试框架位,您可以将您的测试标记为[Asynchronous]
:
using System;
using System.Net;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Silverlight.Testing;
[TestClass]
public class WebRequestsTests : WorkItemTest
{
[TestMethod, Asynchronous]
public void TestWebRequest()
{
var webRequest = WebRequest.CreateHttp("http://www.stackoverflow.com");
webRequest.BeginGetResponse(result =>
{
EnqueueCallback(() =>
{
WebResponse response = webRequest.EndGetResponse(result);
// process response
TestComplete(); // async test complete
});
}, null);
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您希望使用 Rx(我个人也是这么做的),我最近发表了一篇博客文章,介绍如何在使用 SL 测试框架时使基于 Rx 的异步测试变得更清晰。
归档时间: |
|
查看次数: |
9413 次 |
最近记录: |