发出同步 AJAX 请求时 IUriToStreamResolver 中的死锁
Deadlock in IUriToStreamResolver when making synchronous AJAX requests
我正在尝试使用 IUriToStreamResolver 将我的应用程序资源注入 Windows 8.1 WinRT WebView,如下所述:https://blogs.msdn.microsoft.com/wsdevsol/2014/06/20/a-primer-on-webview-navigatetolocalstreamuri/
但是,每次我从 JavaScript 启动同步 XHR 时,应用程序显然都会遇到死锁。相同的代码在 Windows 10 UWP 应用程序中运行良好。
不幸的是我必须使用同步请求。是否可以避免死锁?
index.html:
<!DOCTYPE html>
<html>
<head><title>Test</title></head>
<body>
<span id="progress">Loading...</span>
<script type="text/javascript">
// Set timeout to show the page before causing the deadlock
setTimeout(function () {
var xhr = new XMLHttpRequest();
xhr.open('GET', '/index.html', /* async */ false);
xhr.onload = function () {
/* this will never be called... */
document.getElementById('progress').textContent = 'Success';
};
xhr.onerror = function () {
/* this will never be called... */
document.getElementById('progress').textContent = 'Error';
};
xhr.send();
}, 1000);
</script>
</body>
</html>
MainPage.xaml.cs:
private void Page_Loaded(object sender, RoutedEventArgs e) {
// webview is <WebView x:Name="webview" />
var uri = webview.BuildLocalStreamUri("Test", "index.html");
webview.NavigateToLocalStreamUri(uri, new StreamUriWinRTResolver());
}
// I took this from the MSDN example
public sealed class StreamUriWinRTResolver : IUriToStreamResolver {
public IAsyncOperation<IInputStream> UriToStreamAsync(Uri uri) {
if (uri == null)
throw new Exception();
string path = uri.AbsolutePath;
return GetContent(path).AsAsyncOperation();
}
private async Task<IInputStream> GetContent(string path) {
try {
// Load directly from appx in this example
Uri localUri = new Uri("ms-appx://" + path);
// This line is causing the app to hang:
StorageFile f = await StorageFile.GetFileFromApplicationUriAsync(localUri);
IRandomAccessStream stream = await f.OpenAsync(FileAccessMode.Read);
return stream;
} catch (Exception) { throw new Exception("Invalid path"); }
}
}
在我的例子中,解决方案是用 C++ 编写 IUriToStreamResolver。
我使用了 Microsoft 提供的这个示例 class,它不会导致同步 XHR 出现问题:https://code.msdn.microsoft.com/HTML-WebView-control-sample-56e773fa/sourcecode?fileId=99260&pathId=523934392
我无法真正解释为什么这会有所不同,但 UWP 行为不同的事实让我认为这可能是框架中的错误。
我正在尝试使用 IUriToStreamResolver 将我的应用程序资源注入 Windows 8.1 WinRT WebView,如下所述:https://blogs.msdn.microsoft.com/wsdevsol/2014/06/20/a-primer-on-webview-navigatetolocalstreamuri/
但是,每次我从 JavaScript 启动同步 XHR 时,应用程序显然都会遇到死锁。相同的代码在 Windows 10 UWP 应用程序中运行良好。
不幸的是我必须使用同步请求。是否可以避免死锁?
index.html:
<!DOCTYPE html>
<html>
<head><title>Test</title></head>
<body>
<span id="progress">Loading...</span>
<script type="text/javascript">
// Set timeout to show the page before causing the deadlock
setTimeout(function () {
var xhr = new XMLHttpRequest();
xhr.open('GET', '/index.html', /* async */ false);
xhr.onload = function () {
/* this will never be called... */
document.getElementById('progress').textContent = 'Success';
};
xhr.onerror = function () {
/* this will never be called... */
document.getElementById('progress').textContent = 'Error';
};
xhr.send();
}, 1000);
</script>
</body>
</html>
MainPage.xaml.cs:
private void Page_Loaded(object sender, RoutedEventArgs e) {
// webview is <WebView x:Name="webview" />
var uri = webview.BuildLocalStreamUri("Test", "index.html");
webview.NavigateToLocalStreamUri(uri, new StreamUriWinRTResolver());
}
// I took this from the MSDN example
public sealed class StreamUriWinRTResolver : IUriToStreamResolver {
public IAsyncOperation<IInputStream> UriToStreamAsync(Uri uri) {
if (uri == null)
throw new Exception();
string path = uri.AbsolutePath;
return GetContent(path).AsAsyncOperation();
}
private async Task<IInputStream> GetContent(string path) {
try {
// Load directly from appx in this example
Uri localUri = new Uri("ms-appx://" + path);
// This line is causing the app to hang:
StorageFile f = await StorageFile.GetFileFromApplicationUriAsync(localUri);
IRandomAccessStream stream = await f.OpenAsync(FileAccessMode.Read);
return stream;
} catch (Exception) { throw new Exception("Invalid path"); }
}
}
在我的例子中,解决方案是用 C++ 编写 IUriToStreamResolver。
我使用了 Microsoft 提供的这个示例 class,它不会导致同步 XHR 出现问题:https://code.msdn.microsoft.com/HTML-WebView-control-sample-56e773fa/sourcecode?fileId=99260&pathId=523934392
我无法真正解释为什么这会有所不同,但 UWP 行为不同的事实让我认为这可能是框架中的错误。