2011-03-04 79 views
4

我正在使用WatiN來解析我的網站。我有一個啓動過程的按鈕。我打開瀏覽器窗口並導航到需要的位置,然後創建一個調用DoWork方法的新任務。c#的幫助任務類

我的問題是,如果我在DoWork末尾調用一個新方法來做其他事情,當我嘗試讓程序導航我的網站時,會得到奇怪的結果,但是,如果我不從這個方法調用這個新方法DoWork只需將新方法掛鉤到一個按鈕,點擊所有工作正常。所以我的問題是我不正確地調用我的新方法從後臺處理方法,Dowork

代碼:

IE browser = new IE("http://www.mywebsite.com/"); 
    string startYear; 
    string endYear; 
    int NumRows; 
    Task myThread; 
    public Form1() 
    { 
     InitializeComponent(); 

    } 

    private void Start_Click(object sender, EventArgs e) 
    { 
     startYear = txtStartYear.Text; 
     endYear = txtEndYear.Text; 
     //website navigation work removed for brevity 

     browser.Button(Find.ById("ContentPlaceHolder1_btnApplyFilter")).Click(); 


     int numRows = browser.Div(Find.ById("scroller1")).Table(Find.First()).TableRows.Count -1; 
     NumRows = numRows; 
     lblTotalRows.Text = numRows.ToString(); 
     myThread = Task.Factory.StartNew(() => DoWork()); 


    } 
    public void DoWork() 
    { 
     List<string> myList = new List<string>(NumRows); 
     txtStartYear.Text = startYear; 
     txtEndYear.Text = endYear; 

     for (int i = 1; i < NumRows; i++) 
     { 
      TableRow newTable = browser.Div(Find.ById("scroller1")).Table(Find.First()).TableRows[i]; 
      string coll = string.Format("{0},{1},{2},{3},{4}", newTable.TableCells[0].Text, newTable.TableCells[1].Text, newTable.TableCells[2].Text, newTable.TableCells[3].Text, newTable.TableCells[4].Text); 
      myList.Add(coll); 

      label1.Invoke((MethodInvoker)delegate 
      { 
       label1.Text = i.ToString(); 
      }); 
     } 
     //database work removed for brevity. 

     browser.Button(Find.ById("btnFilter")).Click(); 

     newMethod(); 


    } 
    public void newMethod() 
    { 

     int start = int.Parse(startYear); 
     start++; 
     startYear = start.ToString(); 

     int end = int.Parse(endYear); 
     end++; 
     endYear = end.ToString(); 

     browser.SelectList(Find.ById("selStartYear")).SelectByValue(startYear); 
     browser.SelectList(Find.ById("selEndYear")).SelectByValue(endYear); 

    //removed for brevity 

    } 

} 

再次重申,如果我叫newMethodDoworkbrowser.SelectList(Find.ById("selStartYear")).SelectByValue(startYear)工作不正常,但如果我從Dowork刪除調用newMethod,只是掛鉤newMethod到一個按鈕,它工作正常。我想知道它是否與DoWork是背景任務有關?

當我說它行爲不正常時,我的意思是,當您從下拉列表中選擇一個項目時,頁面會自動發回,但上面的代碼行選擇它,但頁面不會回發,應該是不可能的。如果我沒有在DoWork之內調用該方法,我沒有這個問題。

回答

2

您正在修改非UI線程的UI元素。您已經在DoWork中獲得了代碼,通過Control.Invoke - 您需要爲newMethod做同樣的事情。這很可能是最簡單的辦法來調用UI線程的整個方法:

// At the end of DoWork 
Action action = newMethod; 
label.BeginInvoke(action); 

(我使用label.BeginInvoke因爲我不知道瀏覽器本身是一個「正常」的控制 - 但使用label會如果browser.BeginInvoke編譯,這將更清晰。)

+0

thankyou soooo much ...所以如果我不是首先從非UI線程修改UI元素,我還需要調用'newMethod'嗎? – 2011-03-04 07:07:34

+0

@Nick:假設你沒有做任何其他要求你進入特定線程的東西,那就沒問題。 – 2011-03-04 07:09:59

+0

感謝您編輯您的答案並添加最後一點,這很好理解。另外,我嘗試瀏覽器,它不工作。它說WatiN core.IE不包含'Invoke'的定義,所以有你的答案。 – 2011-03-04 07:13:39

0

我懷疑這是選擇列表控件的問題。當我瀏覽網站時,我有時通過鍵盤選擇下拉項目。有時,它只是不回發,而使用鼠標總是保證回發。

我想你可能會更好地放一個額外的按鈕,並做一個browser.Button(Find.ById("btnFilter")).Click();種事情來調用回發。

如果瀏覽器中的函數沒有執行正確的交叉線程檢查,那麼Jon Skeet應該有所幫助。

+0

感謝您的建議,喬恩的答案解決了我的問題。 – 2011-03-04 07:24:38