在进行同步AJAX请求时IUriToStreamResolver中的死锁

时间:2016-05-06 18:30:31

标签: c# windows-store-apps winrt-xaml

我正在尝试使用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"); }
    }
}

1 个答案:

答案 0 :(得分:0)

在我的例子中,解决方案是在C ++中编写IUriToStreamResolver。

我使用了Microsoft提供的这个示例类,它不会导致同步XHR出现问题:https://code.msdn.microsoft.com/HTML-WebView-control-sample-56e773fa/sourcecode?fileId=99260&pathId=523934392

我无法解释为什么会有所不同,但UWP行为不同的事实让我觉得这可能是框架中的一个错误。