Busy wait with threads

Basically, I need to tackle until some html appears on the web page. I created the following code for me: [/ p>

public void ExecuteBusyWaitThreads() { foreach (Canidate canidate in allCanidates) { Thread newThread = new Thread(delegate() { BusyWait(canidate); }); newThread.Start(); } } public bool BusyWait(Canidate canidate) { //hit that url, and wait for the claim all button to appear string page = null; while (found == false) { HttpWebRequest request = Canidate.GetHTTPRequest(canidate.URL); //make sure we add the authentication cookes to the request request = Canidate.AddCookiesToRequest(request, canidate.GetCookies()); page = new Canidate().GetPage(request); if (page.ToLower().Contains("claim all")) { found = true; NotifyAllThreads(); } } return true; } 

So, if I had 8 canidates , it would canidates 8 threads, each of which is looking for claim all to display on the web page. found is a global variable. As soon as one of the threads finds claim all , all of them must fulfill the guarantee.

I have a couple of questions about this approach. Firstly, this is a good approach. Secondly, each thread will receive its own β€œcopy” of the lively wait function. By this I mean whether one thread can supersede another and change the data in this function, or each of them gets a copy of the variables declared inside the function. Please note that both of these functions are inside the same object.

+3
source share
4 answers

Before answering your questions, I must indicate that you have committed a flagrant act of closing a variable loop .

First of all, this is a good approach.

No, not at all. Creating threads arbitrarily is usually not a good idea. It is better to use stream merging methods. This can be done using the ThreadPool.QueueUserWorkItem or Task class.

Secondly, each thread will receive its own β€œcopy” of the lively wait function. By this I mean whether one thread can supersede another and change the data into this function, or each of them gets a copy of the declared variables inside the function.

Each running instance of BusyWait will receive its own copy of all local variables (i.e. page and request ). Since found declared (presumably in any case) in a non-local area, it will be used for all running BusyWait instances. As a result, your current reads and writes to found are not thread safe, since there are no synchronization mechanisms on it.

+5
source

Secondly, each thread will receive its own β€œcopy” of the lively wait function.

Each thread will perform a function with its own stack space, so this means that any variable local inside your function will belong to the thread in which it is executed. If you have a global variable, for example, your found variable changes inside a function, you need to configure the synchronization mechanism so that access to it does not arise from several threads at the same time, as this will make it difficult to find errors and there will be many horrors that you never want imagine!

+2
source

All threads get their own copies of local variables (only the string page in this case).

Your shared variable found must be declared volatile

This is a rare situation where calling Thread.Sleep() can be beneficial. Insert a little break between calls on the same site.

+2
source

Each thread starts with its own copy of the variables.

However, I would modify my appoarch. Using the found variable is not thread safe. It is possible that more than one thread will change at a time. It is also very possible that one thread will read it and the other will write it. [lock][1] can avoid this.

The best way to solve this problem is to use EventWaitHandle . This way, you don’t have to worry about blocking, and you can build a sleep or timeout, so if "require-all" does not appear, the threads will not work longer than you want.

 internal class ExampleOnExecute { private static EventWaitHandle _stopEvent; public static EventWaitHandle StopEvent { get { return _stopEvent ?? (_stopEvent = new EventWaitHandle(false, EventResetMode.ManualReset)); } } public static void SpinOffThreads(IEnumerable<object> someCollection) { foreach(var item in someCollection) { // You probably do not want to manualy create a thread since these ideally would be small workers // and action BeingInvoke runs in the ThreadPool Action<object> process = BusyWait; process.BeginInvoke(item, null, null); } } private static void BusyWait(object obj) { // You can wait for however long you like or 0 is not waiting at all const int sleepAmount = 1; // Blocks the current thread until the current instance receives a signal, using // a System.TimeSpan to specify the time interval. // // Parameters: // timeout: // A System.TimeSpan that represents the number of milliseconds to wait, or // a System.TimeSpan that represents -1 milliseconds to wait indefinitely. // // Returns: // true if the current instance receives a signal; otherwise, false. while (!StopEvent.WaitOne(TimeSpan.FromMilliseconds(sleepAmount))) { // Do you work here var foundIt = DidIFindIt(); if (foundIt) { // Signal all threads now to stop working we found it. StopEvent.Set(); } } } private static bool DidIFindIt() { return true; } } 

Here is a great FREE threading book.

+2
source

Source: https://habr.com/ru/post/910289/


All Articles