WP7 HttpWebRequest检查文件是否存在(同步)

时间:2011-03-18 20:34:15

标签: silverlight mvvm windows-phone-7

我需要检查文件是否存在,我需要在代码中的几个位置执行此操作。 我可以通过回调处理它的一些地方(有点难看,但它会起作用)。但我不知道如何处理的那个似乎要求它是同步的。

我需要调用该方法来检查RelayCommand中是否存在“canExecute”方法。 关于如何处理这个的任何想法?

这是我目前所拥有的,但在UI线程上调用.WaitOne会阻止后台工作程序,因此它会完全锁定应用程序。

private bool FileExists(Uri file)  
    {  
        var exists = false;

        ManualResetEvent resetEvent = new ManualResetEvent(false);
        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += (s, e) =>{

            WebRequest request = HttpWebRequest.Create(file);
            request.Method = "HEAD"; //only request the head so its quick

            request.BeginGetResponse(result =>
            {
                try
                {
                    //var response = request.EndGetResponse(result);
                    var req = (HttpWebRequest)result.AsyncState;
                    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);

                    exists = (response.StatusCode.ToString() == "OK");
                }
                catch
                {
                    exists = false;

                }
                resetEvent.Set();
            }
            , request);
        };

        worker.RunWorkerAsync();
        resetEvent.WaitOne();

        return exists;
    }

3 个答案:

答案 0 :(得分:1)

你永远不应该在UI线程上使HTTPWebRequest同步 - 这可能会阻止UI几秒钟或几分钟......

如果你真的想让HTTPWebRequest看起来在后台线程上是同步的,那么只需在回调中使用ManualResetEvent - 例如类似的东西:

var resetEvent = new ManualResetEvent();
theHttpWebRequest.BeginGetResponse((result) => {
       var response = theHttpWebRequest.EndGetResponse(result);
       // use response.StatusCode to check for 404?
       resetEvent.Set();
    });
resetEvent.WaitOne();

此外,请注意,通过调用检查的小型Web服务来检查文件是否存在于HTTP上可能会更好 - 这取决于您正在检查的文件的大小。

答案 1 :(得分:0)

AFAIK这是不可能的。您永远不能在Silverlight中对Web服务进行同步调用。

您必须将 canExecute 方法留空(以便始终执行命令),并进行异步调用以检查该命令的处理程序中是否存在文件。该命令的实际代码必须在该异步调用的处理程序中执行。

我认为只有这样才能管理它。

btw-您可以使用lambda表达式使其看起来更像同步代码。或者,Reactive Extensions可能有助于更好看的代码jesse's tutorial)。

答案 2 :(得分:0)

我接近这个问题的方法是创建某种标志(即IsFileExists)并从CanExecute方法返回该标志。 Flag shold最初设置为false,并且假设我们知道文件确实退出时我们认为它没有被禁用。接下来我将触发HTTPWebRequest或wcf调用或任何其他异步方法来检查文件是否存在。一旦回调确认文件存在,将set flag设置为true并触发CanExecuteChanged事件。如果你想要花哨,你可以在等待响应时添加一些视觉反馈。一般来说,用户体验比在网络请求期间锁定屏幕要好得多。