开发者

webClient Bot - Multithreading

I'm making bot for online game. It works, but it is singlethread application.

I want to make it multithread application. I know how background worker works.

To all my tasks I use one WebClient with added Cookie support.

My for example needs to open one page, wait 10 min and do next instruction. I also want to be able to stop bot at any time.

Do I have to pass my WebClient object to background worker to work with? What is the best way to update controls on my Form?

I have one class that has all the values that I want to show on Main Form. Should I fire some event when property changes? If yes, can you give me example?


UPDATE:

This is my Special 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;
        }
    }

}

Is this good way of updating UI? Or is there any beter?

    public void SetStatus(string status)
    {
    开发者_JAVA百科    if (TransferLeftLabel.Dispatcher.Thread == Thread.CurrentThread)
        {
            TransferLeftLabel.Text = status;
        }
        else
        {
            TransferLeftLabel.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
            (Action)(() => {  SetStatus(string status); }));
        }
    }


This is how I would do it:

First: I like to manage threads manually instead of using the BackgroundWorker control when making multithreads applications like the one you want to modify.

To start a new thread, it is as simple as:

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
}

You can get as many Thread instances as you want, store them in a list, and manage how you prefer. However, it isn't true that the more threads the better. Search in Google.

About opening pages and keeping Cookies.

I think you could have an instance of a class in your Form, or where you have the logic (some place that threads can access), (let's name it WebUtils) with a method like: GoToUrl(<url here>) or something like that, and a CookieCollection as a field in that class to keep cookies.

Something you should take in count:

When calling GoToUrl, you might need to do lock when accessing the cookies variable, to avoid inconsistency.

About updating controls:

You can create an event inside the class WebUtils, and everytime the page is accessed you can fire this event. Before starting the threads, you must subscribe to the event in your Form, you can do something similar with lock when updating/accessing/modifying controls in your form.

Now, how to avoid the message Control ____ accessed from a thread other than the thread it was created...?

Here's an example:

If you want to modify property Text of the control textBox1, instead of just doing:

textBox1.Text = "Ey, I accessed the site

you can do:

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

Make sure all the modifications are done like that.

This is just an overview. I'm not a thread expert.
Here is good reference about threadings in general: Threading in C#

Edit:
Take a look at the IsBackground property of threads. That could be the cause of application freezes when you just want to cose it.

I suggested creating a class WebUtils, or however you want to name, because that's how I've created it in the past.

Something like:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜