WP7 HttpWebRequest проверяет, существует ли файл (синхронно) - PullRequest
0 голосов
/ 18 марта 2011

Мне нужно проверить, существует ли файл, и мне нужно сделать это из нескольких мест в коде. В некоторых местах я могу справиться с обратным вызовом (довольно уродливо, но это будет работать). Но тот, который я не знаю, как обращаться, кажется, требует, чтобы это было Синхронным.

Мне нужно вызвать метод, чтобы проверить, существует ли он из RelayCommand как метод "canExecute". Любые идеи о том, как справиться с этим?

Это то, что у меня сейчас есть, но вызов .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 ]

1 голос
/ 19 марта 2011

Никогда не следует делать HTTPWebRequest синхронным в потоке пользовательского интерфейса - это может заблокировать пользовательский интерфейс на секунды или минуты ...

Если вы действительно хотите, чтобы 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();

Также обратите внимание, что проверка, существует ли файл по HTTP, может быть лучше выполнена путем вызова небольшого веб-сервиса, который выполняет проверку - это зависит отразмер проверяемого файла.

0 голосов
/ 21 марта 2011

Я хотел бы подойти к этой проблеме, создав некоторый флаг (например, IsFileExists) и вернуть этот флаг из метода CanExecute. Сначала флаг должен быть установлен в false, а ваша кнопка отключена при условии, что до тех пор, пока мы не узнаем, что файл действительно завершился, мы считаем, что этого не происходит. Затем я бы запустил HTTPWebRequest или вызов wcf или любой другой асинхронный метод, чтобы проверить, существует ли файл. Как только обратный вызов подтвердит, что файл существует, установите флаг в true и запустите событие CanExecuteChanged. Если вы хотите проявить фантазию, вы можете добавить визуальную обратную связь, ожидая ответа. В целом, пользовательский опыт был бы намного лучше, чем блокировка экрана на время веб-запроса.

0 голосов
/ 19 марта 2011

AFAIK это невозможно. Вы никогда не можете делать синхронные звонки на веб-сервисы в Silverlight.

Вы должны оставить метод canExecute пустым (чтобы всегда выполнять команду) и сделать асинхронный вызов, чтобы проверить, существует ли файл в обработчике команды. Настоящий код команды должен выполняться в обработчике для этого асинхронного вызова.

Я думаю, что это единственный способ справиться с этим.

Кстати, вы можете использовать лямбда-выражения, чтобы выглядело больше как синхронный код . Или, возможно, Reactive Extensions могут помочь с более привлекательным кодом ( учебник Джесси ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...