我需要检查文件是否存在,我需要在代码中的几个位置执行此操作。 我可以通过回调处理它的一些地方(有点难看,但它会起作用)。但我不知道如何处理的那个似乎要求它是同步的。
我需要调用该方法来检查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;
}
答案 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事件。如果你想要花哨,你可以在等待响应时添加一些视觉反馈。一般来说,用户体验比在网络请求期间锁定屏幕要好得多。