除非调用线程空闲(方法已完成),否则不会调用 WebRequest 的回调
这是我的代码(它是 Silverlight!):
public class ThreadTester
{
public void Test()
{
Debug.WriteLine("Outer thread start");
ThreadPool.QueueUserWorkItem(x => RunInner());
Thread.Sleep(2000);
Debug.WriteLine("Outer thread end");
}
private void RunInner()
{
Debug.WriteLine("Inner thread start");
BL bl = new BL();
bl.Run1(AssyncCallback);
Debug.WriteLine("Inner thread end");
}
public void AssyncCallback(IAsyncResult ar)
{
Debug.WriteLine("Async Callback called!");
}
}
public class BL
{
public void Run1(AsyncCallback callback)
{
WebRequest req = WebRequest.Create(@"http://microsoft.com");
req.BeginGetResponse(callback, null);
}
}
这是我在输出窗口中得到的:
Outer thread start
Inner thread start
Outer thread end
Inner thread end
Async Callback called!
你知道为什么它会这样工作吗?不应该吗
Outer thread start
Inner thread start
Async Callback called!
Inner thread end
Outer thread end
主要重点是回调调用。
提前致谢
Here is my code (It's Silverlight!):
public class ThreadTester
{
public void Test()
{
Debug.WriteLine("Outer thread start");
ThreadPool.QueueUserWorkItem(x => RunInner());
Thread.Sleep(2000);
Debug.WriteLine("Outer thread end");
}
private void RunInner()
{
Debug.WriteLine("Inner thread start");
BL bl = new BL();
bl.Run1(AssyncCallback);
Debug.WriteLine("Inner thread end");
}
public void AssyncCallback(IAsyncResult ar)
{
Debug.WriteLine("Async Callback called!");
}
}
public class BL
{
public void Run1(AsyncCallback callback)
{
WebRequest req = WebRequest.Create(@"http://microsoft.com");
req.BeginGetResponse(callback, null);
}
}
This is what I get in output window:
Outer thread start
Inner thread start
Outer thread end
Inner thread end
Async Callback called!
Any ideas why it works that way? Shouldnt it be
Outer thread start
Inner thread start
Async Callback called!
Inner thread end
Outer thread end
Main emphasis is on Callback call.
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
回调的要点是,只有在请求完成并收到响应后才调用它。
这似乎花费了超过 2 秒的时间,因此线程结束消息发生在回调之前。
此外,一旦 2 秒结束,
外部线程结束
就会被写入,而RunInner()
内的所有内容都是同步发生的,因此内部线程结束
直到请求完成之后才会显示(但在回调执行之前,因为您使用的是异步BeginGetResponse
)。当我运行相同的代码时,我实际上得到了以下输出:
这仅意味着该请求对我而言花费了不到 2 秒的时间。如果将 Thread.Sleep() 值增加几秒,您应该会得到相同的结果。不过,回调是异步调用的,因此内部线程结束消息通常会先于它,但对于异步处理,您不应该依赖它。
如果不清楚,请在评论中告诉我,我会尽力进一步说明。
编辑
现在我看到您正在使用 Silverlight,问题变得更加清晰。我认为,如果您将其实际调用
EndGetResponse()
,您最终会得到SecurityException
,因为 Silverlight 希望通过以下方式阻止跨站点脚本攻击:默认。也就是说,如果没有建立允许访问的策略,您将无法访问与 Silverlight 应用程序所在域(例如 microsoft.com 或 google.com)不同的域中的 URL。这里有安全策略的详细处理:http ://msdn.microsoft.com/en-us/library/cc645032(v=VS.95).aspx
The point of the callback is that it is something to invoke only after your request is complete and your response is received.
This appears to be taking more than 2 seconds, so the thread end messages happen before the callback.
Further, the
Outer thread end
gets written as soon as the 2 seconds is up, whereas everything withinRunInner()
happens synchronously, soInner thread end
doesn't show up until after the request is complete (but before the callback executes, because you are using the asynchronousBeginGetResponse
).When I run your same code, I actually get this output:
This just means that the request took less than 2 seconds for me. If you increase your
Thread.Sleep()
value by a few seconds, you should get the same result. Again, though, the callback is being invoked asynchronously, so theInner thread end
message will typically precede it, but with asynchronous processing you should not rely on that.Let me know in the comments if this is not clear, and I will try to illustrate further.
edit
Now that I see that you are using Silverlight, the issues are becoming clearer. I think that if you take this through to actually calling
EndGetResponse()
, you'll end up with aSecurityException
, because Silverlight wants to block cross-site scripting attacks, by default. That is, you can't access URLs in domains different than the one in which your Silverlight application lives (like microsoft.com or google.com) without establishing a policy that allows it.There is a detailed treatment of security policies here: http://msdn.microsoft.com/en-us/library/cc645032(v=VS.95).aspx
在我的本地计算机上运行良好,其中 testGet.htm 是 SL 应用程序的本地计算机。
消息框显示开始,运行调用,内部,确定,然后 5 秒后完成
编辑:
如果我们像您建议的那样进行以下代码更改,您理论上的建议不可能起作用:
您不能期望显示“outer结束”之前显示的任何消息框,因为
如果ThreadPool MaxThreads为1,它相当于调用。您不能期望“two”会在“one结束”之前显示,它不能在第一个执行的中间注入排队的代表。
Works fine with my local machine where testGet.htm is local to SL application.
Message boxes are shown began ,run called, inside, ok and then 5 secs later finished
Edit:
What you are suggesting in theory cant possibly work, if we have following code change like u suggest:
You cannot expect any message box to be shown before "outer ended" is shown because its equivalent to calling
if ThreadPool MaxThreads was 1. You cannot expect that "two" will be shown before "one ended" , it cannot inject in the middle of execution of first queued delegate.