【问题标题】:While loop program flowWhile循环程序流程
【发布时间】:2013-07-23 17:04:17
【问题描述】:

我在创建的 while 循环中遇到了程序流问题。

while (reader.Read())
{
    // Store scenario information
    int Id = (int)reader["ScenarioID"];
    string Data = reader["ScenarioData"].ToString();
    string Url = "http://google.com";

    // Initialize result information
    int HasSucceeded = 0;
    var screenshot = new Byte[] { };

    // Navigate to webBrowser
    webBrowser2.Navigate(Url);
    webBrowser2.DocumentCompleted += WebBrowserDocumentCompleted;

    // Do test
    TestScenarios(Url, HasSucceeded);

    // Take screenshot
    TakeScreenshot(screenshot);

    // Insert results
    InsertResults(Id, HasSucceeded, screenshot);

    // Mark scenario for deletion
    MarkScenario(Id);
}

private void WebBrowserDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs Url)
{
    MessageBox.Show("Operation has completed!");
}

程序的预期流程应该是

  1. 读取表格中的一项
  2. 初始化一些变量/存储一些值
  3. 将 webBrowser 控件导航到 URL
  4. webBrowser 控件完成后,进行测试
  5. 截图
  6. 将结果插入新表
  7. 将原表中的项目标记为删除
  8. 循环回到#1,直到所有项目都被覆盖。

但是,发生的情况是 while 循环中的所有内容都按照 except 的顺序正常运行 webBrowser2.Navigate 行,在 while 循环退出之前不会显示 Url。在 URL 显示后,立即出现 5 条连续消息“操作已完成”(针对表中的 5 项)。如何修复我的流程?

【问题讨论】:

    标签: c# flow


    【解决方案1】:

    试试这个解决方案。将循环包装在 UI 线程之外的另一个线程中。然后使用AutoResetEvent

    new Thread(() =>
    {
        AutoResetEvent signal = new AutoResetEvent(false);
        while (reader.Read())
        {
            // Store scenario information
            int Id = (int)reader["ScenarioID"];
            string Data = reader["ScenarioData"].ToString();
            string Url = "http://google.com";
    
            // Initialize result information
            int HasSucceeded = 0;
            var screenshot = new Byte[] { };
    
            Action action = () =>
            {
                 webBrowser2.Tag = signal;
                 // Navigate to webBrowser
                 webBrowser2.Navigate(Url);
                 webBrowser2.DocumentCompleted -= WebBrowserDocumentCompleted;
                 webBrowser2.DocumentCompleted += WebBrowserDocumentCompleted;
            };
            webBrowser2.Invoke(action);
    
            signal.WaitOne();//Wait till it finishes
    
            // Do test
            TestScenarios(Url, HasSucceeded);
    
            // Take screenshot
            TakeScreenshot(screenshot);
    
            // Insert results
            InsertResults(Id, HasSucceeded, screenshot);
    
            // Mark scenario for deletion
            MarkScenario(Id);
        }
    }).Start();
    
        private void WebBrowserDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs Url)
        {
            MessageBox.Show("Operation has completed!");
            ((AutoResetEvent)((WebBrowser)sender).Tag).Set();
        }
    

    我要求工作线程等到文档加载后再继续执行。很简单。

    希望对你有帮助

    【讨论】:

    • 我收到“阅读器关闭时调用读取的尝试无效”,但感谢您的示例,我正在努力。
    • 你在哪里打电话connection.close()?不要在这个块之外调用它,而是在 while 循环之后调用 connection.close()
    • 所以,我在 while 循环之后立即调用 reader.Close();,但我认为是 Start(); 行导致了异常,因为当我删除该行时,我没有得到异常,但是还是不行。
    【解决方案2】:

    Navigate 方法可能正在排队一个事件,稍后将在您的代码正在运行的同一线程(UI 线程)上处理该事件。您可能必须将代码放入单独的 background worker thread 中,以便在循环完成之前处理 UI 事件。

    【讨论】:

      【解决方案3】:

      如果您正在开发 .NET 4.5 框架,我建议您检查 asyncawait 操作。这可能会解决您的问题。 Async and Await in MSDN

      【讨论】:

      • 注意 async 和 await 是在 .NET 4.5 中引入的
      猜你喜欢
      • 2014-04-01
      • 2020-09-28
      • 2022-01-14
      • 2016-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      相关资源
      最近更新 更多