我正在重写一些使用WebBrowser
对象的代码,以确定服务器何时可以下载文件。总的来说,行为是这样的,首先将文件上传到服务器,一旦上传服务器然后开始工作,因为它正在工作,它将连接到它所服务的特定页面的用户重定向到各种URL,直到它完成,一次完成后,文件就可以下载了。
我希望在单个函数调用中具有所有这些行为,基本上是GetFileFromServer()
。一旦此调用返回,则文件位于指定的文件路径。
问题是当使用WebBrowser
我必须处理Navigated
事件以确定文件何时可以下载时,这会使程序流离开GetFileFromServer
函数。我可以有一个小的循环
while(fileNotDownloaded)
Thread.Sleep(500);
但我想改用Task
,以便该函数看起来像
public void GetFileFromServer()
{
UploadFile(); // Blocks until file is uploaded
DownloadFile(); // Blocks until file is downloaded
}
我已经实施了UploadFile
但是,再次遇到DownnloadFile
的问题。基本上我希望我的功能看起来像这样
private void DownloadFile()
{
var DoWebDriverTask = Task.Factory.StartNew(() =>
{
Boolean fileReady = false;
WebBrowser webBrowser = new WebBrowser();
webBrowser.Url = new Uri(MySpecificIP);
webBrowser.Navigated += WebBrowserNavigated;
// Sit and Spin until the specific URL is navigated to
while(!fileReady)
Task.WaitAll(new Task[] { Task.Delay(500) });
DownloadFile();
private void WebBrowserNavigated(object sender, WebBrowserNavigatedEventArgs e)
{
if(e.Url.AbsoluteUri.ToString().Contains("mySpecificURLString"))
fileReady = true;
}
}, CancelWaitForDownloadTaskToken);
Task.WaitAll(new Task[] { WebDriverTask });
}
但这显然不是正确的代码。我也理解这是我在上面提供的解决方案,但只是移到了Task
,但它确实给了我GetFileFromServer
的行为。请注意,UI线程中没有一个是按原样进行的,所以我上面提供的解决方案也是可行的...但是使用Task
如果用户我可以取消等待下载希望。
那么有没有办法处理Navigated
中的事件Task
,正如我在上面的代码中描述的那样?
答案 0 :(得分:1)
以下是在同一方法范围内处理事件的方法:
webBrowser.Navigated += (s, e) =>
{
if (e.Url.AbsoluteUri.ToString().Contains("mySpecificURLString"))
fileReady = true;
};
然而,循环和等待不是一个好主意,这是一个更好的选择:
private Task WaitBeforeDownloadFile(WebBrowser webBrowser)
{
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
WebBrowserNavigatedEventHandler web_browser_on_navigated = null;
web_browser_on_navigated = (s, e) =>
{
if (e.Url.AbsoluteUri.ToString().Contains("mySpecificURLString"))
{
tcs.TrySetResult(true);
webBrowser.Navigated -= web_browser_on_navigated;
}
};
webBrowser.Navigated += web_browser_on_navigated;
return tcs.Task;
}
此方法创建Task
,在Navigated
事件被引发并满足您指定的条件时完成。
以下是您将如何使用它:
private void DownloadFile()
{
WebBrowser webBrowser = new WebBrowser();
webBrowser.Url = new Uri(MySpecificIP);
//Initiate whatever here before waiting for the Navigated event
WaitBeforeDownloadFile(webBrowser).Wait();
//Continue here
}
这也不是一件好事。但是,由于您需要同步行为,因此您必须这样做。
一个更好的替代方案,需要对你的工作方式做很多改变,就是异步做事,这需要大量的学习。这是一个例子:
public async Task GetFileFromServer()
{
await UploadFile();
await DownloadFile();
}
public async Task UploadFile()
{
...
}
public async Task DownloadFile()
{
WebBrowser webBrowser = new WebBrowser();
webBrowser.Url = new Uri(MySpecificIP);
//Initiate whatever here before waiting for the Navigated event
await WaitBeforeDownloadFile(webBrowser);
//Continue here
}