简体   繁体   English

我如何有效管理在主线程中运行的准“任务”

[英]How do a I efficiently manage a quasi 'task' running in the main thread

I'm developing a small internal-use utility to monitor the uptime and responsiveness of several websites. 我正在开发一个小的内部使用实用程序,以监视多个网站的正常运行时间和响应能力。 We have very specialist requirements and criteria to test, hence developing a small application for this. 我们有非常专业的要求和标准进行测试,因此为此开发了一个小型应用程序。

I have to use the WebBrowser Control to load the website as it has decencies on JavaScript and plug ins which are required. 我必须使用WebBrowser控件来加载网站,因为它对JavaScript和插件有要求。 (The test has to be as real world as possible) As a result, my testing has to be run in the GUI thread, currently within the "DocumentCompleted" event. (测试必须尽可能地真实)。结果,我的测试必须在GUI线程中运行,当前在“ DocumentCompleted”事件中。

Additionally, the website I'm testing is AJAX heavy, so I have to implement waiting periods within my logic to ensure that the DOM is loaded as I expect. 另外,我正在测试的网站是AJAX繁重的网站,因此我必须在逻辑中实现等待期,以确保按预期加载DOM。 For example, I check that the tags are present on the logon the page using a while loop. 例如,我使用while循环检查登录页面上是否存在标签。

My proof of concept works as expected and I'm very happy with the results. 我的概念证明按预期工作,我对结果感到非常满意。 However, I'm struggling how to make this more 'task orientated'. 但是,我正在努力使它变得更加“面向任务”。 For example, I need to implement a timeout period and the ability for the user to cancel what's going on. 例如,我需要实现一个超时期限,并让用户能够取消正在发生的事情。 Eg, the logon page may have failed and so will never show the correct inputs. 例如,登录页面可能已失败,因此将永远不会显示正确的输入。

At the moment, the only way I can see is to implement logic at every single step to check for a UserCancel variable or check the stopwatch. 目前,我唯一能看到的方法是在每一步都实现逻辑以检查UserCancel变量或检查秒表。

I fear I've made a fundamentally bad choice in the architecture of my application, so I'm looking for advice on how to implement the above and improve the code. 我担心我在应用程序的体系结构中做出了根本上不好的选择,因此我正在寻找有关如何实现上述内容和改进代码的建议。


private void TestSite(string url){

webBrowser.Naviate(url);
stopwatch.Start();

}

private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {

if(stopwatch.Elapsed.Seconds > timeOutValue || userCancel){
//Task timed out, or user has cancelled
return;
}

//Switch to the relevant application logic
//siteStatus is defined by where I expect the website to be at any particular time. 
switch(siteStatus)
{

     case siteStatus.LogonPage:
     if(DocumentTitle != ExpectedDocumentTitle){

     //Page is unexpected. Handle this and return

     }


     //Title is correct, wait until website has built the DOM
     while(stopwatch.Elapsed.Seconds < timeOutValue || !userCancel || webBrowser1.Document.GetElementsByTagName("input").Count() < 2){

     //Carry on
     Application.DoEvents();

     } 

     if(stopwatch.Elapsed.Seconds > timeOutValue){ return; }
     if(userCancel){ return; } 

     //Business logic goes here. Reports on time taken, ensures correct elements are on the page

     break;

     case siteStatus.Menu:

     //Essentially as above with different logic and tests

     break;

    //etc etc

}

The events based model is probably a better approach; 基于事件的模型可能是更好的方法。 rather than loops. 而不是循环。

I would add some OnPropertyChanged event handlers to the div or container that is being updated by the ajax query as opposed to a loop. 我将一些OnPropertyChanged事件处理程序添加到由ajax查询而不是循环更新的div或容器中。

private void DocumentCompletedHandler(object sender, EventArgs e)
{

    HtmlElement elem = webctrl.Document.GetElementById("ajaxDiv");

    if (elem != null)
    {
          elem.AttachEventHandler("onpropertychange", new EventHandler(ajaxEvent));
    }

}

with the handler 与处理程序

private void ajaxEvent(Object sender, EventArgs e)
{
      HtmlElement div = webctrl.Document.GetElementById("ajaxDiv");
      if (div == null) return;  // Not Found!?
      String contentLoaded = div.InnerHtml; // get the content loaded via ajax
}

With the same structure in mind, you can fire off an an interrupt event or something similar to abort the operation. 考虑到相同的结构,您可以触发一个中断事件或类似的操作来中止该操作。 Or you can use the stop command to stop all processing on the web control - Though I am not certain if this will stop ajax processing. 或者,您可以使用stop命令来停止Web控件上的所有处理-尽管我不确定这是否会停止Ajax处理。

private void BtnAbort_Click(Object sender, EventArgs e)
{
   webctrl.Stop();
   // TODO : Remov any event handlers
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM