webClient Bot - 多线程

问题描述:

我正在为在线游戏制作机器人。 它可以工作,但它是单线程应用程序。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

这是我会怎么做:

第一: 我喜欢管理线程手动,而不是使多线程应用程序,如要修改的一个时,使用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