gpt4 book ai didi

asp.net-mvc - ASP.NET MVC 中未调用 WebClient 异步回调

转载 作者:行者123 更新时间:2023-12-02 17:11:38 26 4
gpt4 key购买 nike

根据 GET 请求,我运行(类似于):

public ActionResult Index(void) {
webClient.DownloadStringComplete += onComplete;
webClient.DownloadStringAsync(...);
return null;
}

我看到 onCompleteIndex() 完成执行之前不会被调用。我可以看到 onComplete 是在与执行 Index 不同的线程上调用的。

问题:为什么会发生这种情况?为什么 webClient 的异步线程明显被阻塞,直到请求处理线程完成?

有没有办法解决这个问题,而无需从ThreadPool启动新线程(我尝试了这个,并且使用线程池确实按预期工作。如果从a调用DownloadStringAsync,webClient的回调也会按预期发生ThreadPool 的线程)。

ASP.NET MVC 3.0、.NET 4.0、MS Cassini 开发 Web 服务器 (VS 2010)

编辑:这是完整的代码:

public class HomeController : Controller {
private static ManualResetEvent done;

public ActionResult Index() {
return Content(DownloadString() ? "success" : "failure");
}

private static bool DownloadString() {
try {
done = new ManualResetEvent(false);
var wc = new WebClient();
wc.DownloadStringCompleted += (sender, args) => {
// this breakpoint is not hit until after Index() returns.
// It is weird though, because response isn't returned to the client (browser) until this callback finishes.
// Note: This thread is different from one Index() was running on.
done.Set();
};

var uri = new Uri(@"http://us.battle.net/wow/en/character/blackrock/hunt/simple");

wc.DownloadStringAsync(uri);

var timedout = !done.WaitOne(3000);
if (timedout) {
wc.CancelAsync();
// if this would be .WaitOne() instead then deadlock occurs.
var timedout2 = !done.WaitOne(3000);
Console.WriteLine(timedout2);
return !timedout2;
}
return true;
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
return false;
}
}

最佳答案

我对此感到好奇,因此我询问了 Microsoft 内部 ASP.NET 讨论别名,并得到了 Levi Broderick 的回复:

ASP.NET internally uses the SynchronizationContext for synchronization, and only one thread at a time is ever allowed to have control of that lock. In your particular example, the thread running HomeController::DownloadString holds the lock, but it’s waiting for the ManualResetEvent to be fired. The ManualResetEvent won’t be fired until the DownloadStringCompleted method runs, but that method runs on a different thread that can’t ever take the synchronization lock because the first thread still holds it. You’re now deadlocked.

I’m surprised that this ever worked in MVC 2, but if it did it was only by happy accident. This was never supported.

关于asp.net-mvc - ASP.NET MVC 中未调用 WebClient 异步回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5718831/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com