2011-04-22 50 views
1

我正在爲在線遊戲製作機器人。 它可以工作,但它是單線程應用程序。webClient Bot - 多線程

我想讓它成爲多線程應用程序。 我知道背景工作者是如何工作的。

對於我所有的任務,我使用一個Web客戶端添加Cookie支持。

我例如需要打開一個頁面,等待10分鐘,然後執行下一條指令。 我也希望能夠隨時停止機器人。

我是否必須將我的WebClient對象傳遞給後臺工作人員才能使用? 什麼是更新我的表單上的控件的最佳方式?

我有一個類具有我想要在主窗體上顯示的所有值。 我應該在財產改變時發生一些事件嗎?如果是的話,你能舉個例子嗎?


UPDATE:

這是我的特別的WebClient:

using System; 
using System.Net; 

namespace Game_Bot 
{ 
    class WebClientEx : WebClient 
    { 
     public CookieContainer CookieContainer { get; private set; } 

     public WebClientEx() 
     { 
      CookieContainer = new CookieContainer(); 
     } 

     public void ClearCookies() 
     { 
      CookieContainer = new CookieContainer(); 
     } 

     protected override WebRequest GetWebRequest(Uri address) 
     { 

      var request = base.GetWebRequest(address); 
      if (request is HttpWebRequest) 
      { 
       (request as HttpWebRequest).CookieContainer = CookieContainer; 
      } 
      return request; 
     } 
    } 

} 

正在更新UI的這個好辦法嗎?或者有任何的煩惱?

public void SetStatus(string status) 
    { 
     if (TransferLeftLabel.Dispatcher.Thread == Thread.CurrentThread) 
     { 
      TransferLeftLabel.Text = status; 
     } 
     else 
     { 
      TransferLeftLabel.Dispatcher.BeginInvoke(DispatcherPriority.Normal, 
      (Action)(() => { SetStatus(string status); })); 
     } 
    } 
+0

如果你想比一個線程的工作比較多,我建議你使用線程改爲手動的'BackgroundWorker'控制。 – 2011-04-22 08:48:27

+2

使用手動線程,您還可以發送所需的任何狀態更新(通過在主線程上調用委託並檢查InvokeRequired)。 Backgroundworker僅支持向用戶界面報告百分比。 – 2011-04-22 08:52:13

+0

@Vladislaw正好。 – 2011-04-22 09:11:37

回答

3

這是我會怎麼做:

第一: 我喜歡管理線程手動,而不是使多線程應用程序,如要修改的一個時,使用BackgroundWorker控制。

要開始一個新的線程,它是那樣簡單:

public void SomeMethod() { 
    var thread = new Thread(MyMethod); 
    thread.Start(); //Will start the method 
} 

public void MyMethod() { 
    //Do whatever you want inside the thread here 
} 

只要你想你可以得到儘可能多的Thread情況下,將它們存儲在一個列表中,並管理你怎麼喜歡。但是,線程越多越好,這是不正確的。在Google中搜索。

關於打開頁面和保留Cookie。我想你可以在你的表單中有一個類的實例,或者你有邏輯的地方(線程可以訪問的某個地方),(我們用WebUtils來命名):GoToUrl(<url here>)或類似的東西,和一個CookieCollection作爲該類中的字段來保持cookie。

你應該採取計數:

當調用GoToUrl,你可能需要訪問餅乾變量時,避免不一致性做lock

關於更新控制:

您可以在類WebUtils中創建一個事件,每次訪問頁面時可以觸發這個事件。在開始線程之前,您必須訂閱Form中的事件,在更新/訪問/修改窗體中的控件時,可以使用類似

現在,如何避免郵件Control ____ accessed from a thread other than the thread it was created...

下面是一個例子:

如果要修改屬性Text控制textBox1的,而不是隻是在做:

textBox1.Text = "Ey, I accessed the site

,你可以這樣做:

MethodInvoker m =() => { textBox1.Text = "Ey, I accessed the site" }; 
if (InvokeRequired) 
    BeginInvoke(m); 
else 
    m.Invoke() 

製作確保所有的修改都是這樣完成的。

這只是一個概述。我不是一個線程專家。
這是一般在螺紋參考:Threading in C#

編輯:
看看線程IsBackground財產。這可能是應用程序凍結的原因,當你只是想要找到它。

我建議創建一個類WebUtils,或者你想命名,因爲這就是我過去創建它的方式。

喜歡的東西:

public class WebUtils { 
    CookieContainer _cookies; 

    public WebUtils() { 
     _cookies = new CookieContainer(); 
    } 

    public void AccessPage(string url) { 
     //Here I create a new instance of a HttpWebRequest class, and assign `_cookies` to its `Cookie` property. 
     //Don't really know if `WebClient` has something similar 
    } 
} 
+0

這非常有幫助。我更新了我的問題。 – Hooch 2011-04-22 10:29:31