Click here to Skip to main content
15,894,546 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
please, help me out what i thought was the answer just falls back to the same thing. I'm a self taught programmer who havn't known much. The timer all run same thing cause it uses ui thread. Please, how do i run two timers to take from a list and browse the web using the info from the list?
My problem is that they all use same item and this is not good because of repitition and i don't even know how to channel 'timers.timer' and 'threading.timer' into this matter to bail me out. Please, your help is greatly needed.

What I have tried:

just inputing into webbrowser bt using synclock with three timers running simultaneously bt they seem to use same item from list because they run on ui thread
Posted
Updated 2-Mar-19 22:23pm
Comments
Slacker007 1-Mar-19 10:09am    
Is this task a little advanced for a beginner? Something to consider.
[no name] 1-Mar-19 21:11pm    
not that advanced. The problem is how to run multiple thread.timer at intervals cause i dönt know how
[no name] 3-Mar-19 12:22pm    
You're getting "solutions"; but since you haven't made clear on why you think you need 3 timers you are probably "solving" the wrong "problem".

There is usually more than one way to solve something, with some solutions a lot better than others; but not if you're not clear in the first place.
CHill60 5-Mar-19 6:03am    
When I advised you to start a new thread I also advised you to post the code. Without seeing your code we cannot possibly help you with why you are always using the same item.

Here is an alternative method based on Asynchronous calls using Async...Await[^].

Async...Await uses the ThreadPool to manage the multitasking. The number of threads executed simultaneously is dependant on the CPU and the number of cores. If you want to change the default setting, the following documentation will explain how: ThreadPool.SetMinThreads(Int32, Int32) Method (System.Threading) | Microsoft Docs[^]

The WebClient[^] class has a DownloadStringTaskAsync[^] method that we can use. We can force the method to run off the UI thread by calling ConfigureAwait(false)[^].

To help us visualize how this work, let us wrap the call in a method:
C#
private static async Task<Tuple<string, string>> GetUrlAsync(Uri url)
{
    Console.WriteLine("thisIsAsyncStart: " 
        + Thread.CurrentThread.ManagedThreadId);

    // make our call on another thread
    var result = await new WebClient()
        .DownloadStringTaskAsync(url).ConfigureAwait(false);

    Console.WriteLine("thisIsAsyncEnd: " + Thread.CurrentThread.ManagedThreadId);

    // return both the uri passed and the data returned
    return new Tuple<string, string>(url.ToString(), result);

    // we return to the UI thread when we exit this method
}

Next, we need a few URIs to call:
C#
private static List<Uri> urls = new List<Uri>()
    {
        new Uri("https://www.codeproject.com", UriKind.Absolute),
        new Uri("https://apple.com", UriKind.Absolute),
        new Uri("https://xamarin.com", UriKind.Absolute),
        new Uri("https://nokia.com", UriKind.Absolute),
        new Uri("https://samsung.com", UriKind.Absolute),
        new Uri("https://www.microsoft.com", UriKind.Absolute),
        new Uri("https://www.codeproject.com", UriKind.Absolute),
        new Uri("https://apple.com", UriKind.Absolute),
        new Uri("https://xamarin.com", UriKind.Absolute),
        new Uri("https://nokia.com", UriKind.Absolute),
        new Uri("https://samsung.com", UriKind.Absolute),
        new Uri("https://www.microsoft.com", UriKind.Absolute),
        new Uri("https://www.codeproject.com", UriKind.Absolute),
        new Uri("https://apple.com", UriKind.Absolute),
        new Uri("https://xamarin.com", UriKind.Absolute),
        new Uri("https://nokia.com", UriKind.Absolute),
        new Uri("https://samsung.com", UriKind.Absolute),
        new Uri("https://www.microsoft.com", UriKind.Absolute),
        new Uri("https://www.codeproject.com", UriKind.Absolute),
        new Uri("https://apple.com", UriKind.Absolute),
        new Uri("https://xamarin.com", UriKind.Absolute),
        new Uri("https://nokia.com", UriKind.Absolute),
        new Uri("https://samsung.com", UriKind.Absolute),
        new Uri("https://www.microsoft.com", UriKind.Absolute),
        new Uri("https://www.codeproject.com", UriKind.Absolute),
        new Uri("https://apple.com", UriKind.Absolute),
        new Uri("https://xamarin.com", UriKind.Absolute),
        new Uri("https://nokia.com", UriKind.Absolute),
        new Uri("https://samsung.com", UriKind.Absolute),
        new Uri("https://www.microsoft.com", UriKind.Absolute),
    };

Now there are two way that I will demonstrate managing multiple tasks at once.

1. WhenAll[^] - Creates a task that will complete when all of the Task objects in an array have completed
C#
private static async Task RunWhenAllAsync()
{
    var tasks = new List<Task<Tuple<string, string>>>();

    foreach (var url in urls)
    {
        tasks.Add(GetUrlAsync(url));
    }

    await Task.WhenAll(tasks.ToArray());

    foreach (var task in tasks)
    {
        var result = task.Result;
        Console.WriteLine($"id: {task.Id} | url {task.Result.Item1} > length: {task.Result.Item2.Length}");
    }
}

Output:
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncEnd: 13
thisIsAsyncEnd: 11
thisIsAsyncEnd: 13
thisIsAsyncEnd: 13
thisIsAsyncEnd: 11
thisIsAsyncEnd: 16
thisIsAsyncEnd: 11
thisIsAsyncEnd: 12
thisIsAsyncEnd: 16
thisIsAsyncEnd: 15
thisIsAsyncEnd: 12
thisIsAsyncEnd: 12
thisIsAsyncEnd: 13
thisIsAsyncEnd: 11
thisIsAsyncEnd: 16
thisIsAsyncEnd: 11
thisIsAsyncEnd: 11
thisIsAsyncEnd: 16
thisIsAsyncEnd: 14
thisIsAsyncEnd: 14
thisIsAsyncEnd: 13
thisIsAsyncEnd: 12
thisIsAsyncEnd: 15
thisIsAsyncEnd: 14
thisIsAsyncEnd: 12
thisIsAsyncEnd: 13
thisIsAsyncEnd: 14
thisIsAsyncEnd: 11
thisIsAsyncEnd: 15
thisIsAsyncEnd: 11
id: 1 | url https://www.codeproject.com/ > length: 96485
id: 3 | url https://apple.com/ > length: 53646
id: 5 | url https://xamarin.com/ > length: 149548
id: 7 | url https://nokia.com/ > length: 73246
id: 9 | url https://samsung.com/ > length: 106147
id: 11 | url https://www.microsoft.com/ > length: 1020
id: 13 | url https://www.codeproject.com/ > length: 96479
id: 15 | url https://apple.com/ > length: 53646
id: 17 | url https://xamarin.com/ > length: 149548
id: 19 | url https://nokia.com/ > length: 73246
id: 21 | url https://samsung.com/ > length: 106147
id: 23 | url https://www.microsoft.com/ > length: 1020
id: 25 | url https://www.codeproject.com/ > length: 96485
id: 27 | url https://apple.com/ > length: 53646
id: 29 | url https://xamarin.com/ > length: 149548
id: 31 | url https://nokia.com/ > length: 73246
id: 33 | url https://samsung.com/ > length: 106147
id: 35 | url https://www.microsoft.com/ > length: 1020
id: 37 | url https://www.codeproject.com/ > length: 96485
id: 39 | url https://apple.com/ > length: 53646
id: 41 | url https://xamarin.com/ > length: 149548
id: 43 | url https://nokia.com/ > length: 73246
id: 45 | url https://samsung.com/ > length: 106147
id: 47 | url https://www.microsoft.com/ > length: 1020
id: 49 | url https://www.codeproject.com/ > length: 96485
id: 51 | url https://apple.com/ > length: 53646
id: 53 | url https://xamarin.com/ > length: 149548
id: 55 | url https://nokia.com/ > length: 73246
id: 57 | url https://samsung.com/ > length: 106147
id: 59 | url https://www.microsoft.com/ > length: 1020

Benefits:

  • code is very simple
  • the UI thread won't be blocked
  • the tasks run in async on seperate threads to the UI
  • the results are in the order the tasks were created, not the order they completed

Disadvantages:

  • execution will wait until all tasks are completed
  • the user won't receive any progress feedback

2. WaitAny[^] - Waits for any of the provided Task objects to complete execution.
C#
private static readonly object lockObj = new object();

private static async Task RunWaitAnyAsync()
{
    var tasks = new List<Task<Tuple<string, string>>>();

    foreach (var url in urls)
    {
        tasks.Add(GetUrlAsync(url));
    }

    while (tasks.Count > 0)
    {
        // index of task completed
        var index = Task.WaitAny(tasks.ToArray());

        // get the task
        var task = tasks[index];

        if (task.IsCompleted) // success
        {
            // retrieve the result
            var result = task.Result;

            // display
            Console.WriteLine($"id: {task.Id} | url {task.Result.Item1} > length: {task.Result.Item2.Length}");

        }
        else if (task.IsFaulted)
        {
            // handled failed here...
        }

        // block collisions & remove the task from the execution list
        lock (lockObj) tasks.Remove(task);
    }
}

Output:
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncStart: 1
thisIsAsyncEnd: 12
thisIsAsyncEnd: 13
id: 11 | url https://www.microsoft.com/ > length: 1020
id: 23 | url https://www.microsoft.com/ > length: 1020
thisIsAsyncEnd: 13
id: 35 | url https://www.microsoft.com/ > length: 1020
thisIsAsyncEnd: 13
id: 47 | url https://www.microsoft.com/ > length: 1020
thisIsAsyncEnd: 11
id: 59 | url https://www.microsoft.com/ > length: 1020
thisIsAsyncEnd: 13
id: 3 | url https://apple.com/ > length: 53646
thisIsAsyncEnd: 16
id: 15 | url https://apple.com/ > length: 53646
thisIsAsyncEnd: 15
id: 27 | url https://apple.com/ > length: 53646
thisIsAsyncEnd: 15
id: 7 | url https://nokia.com/ > length: 73246
thisIsAsyncEnd: 12
id: 39 | url https://apple.com/ > length: 53646
thisIsAsyncEnd: 13
thisIsAsyncEnd: 16
id: 9 | url https://samsung.com/ > length: 106147
id: 21 | url https://samsung.com/ > length: 106147
thisIsAsyncEnd: 13
id: 31 | url https://nokia.com/ > length: 73247
thisIsAsyncEnd: 14
id: 19 | url https://nokia.com/ > length: 73246
thisIsAsyncEnd: 15
id: 55 | url https://nokia.com/ > length: 73247
thisIsAsyncEnd: 17
id: 45 | url https://samsung.com/ > length: 106148
thisIsAsyncEnd: 16
id: 33 | url https://samsung.com/ > length: 106148
thisIsAsyncEnd: 17
id: 57 | url https://samsung.com/ > length: 106147
thisIsAsyncEnd: 16
id: 43 | url https://nokia.com/ > length: 73247
thisIsAsyncEnd: 14
id: 51 | url https://apple.com/ > length: 53646
thisIsAsyncEnd: 11
id: 41 | url https://xamarin.com/ > length: 149548
thisIsAsyncEnd: 12
id: 17 | url https://xamarin.com/ > length: 149548
thisIsAsyncEnd: 16
id: 53 | url https://xamarin.com/ > length: 149548
thisIsAsyncEnd: 15
id: 5 | url https://xamarin.com/ > length: 149548
thisIsAsyncEnd: 15
id: 1 | url https://www.codeproject.com/ > length: 96485
thisIsAsyncEnd: 17
id: 29 | url https://xamarin.com/ > length: 149548
thisIsAsyncEnd: 15
id: 25 | url https://www.codeproject.com/ > length: 96479
thisIsAsyncEnd: 17
id: 49 | url https://www.codeproject.com/ > length: 96479
thisIsAsyncEnd: 11
id: 13 | url https://www.codeproject.com/ > length: 96485
thisIsAsyncEnd: 16
id: 37 | url https://www.codeproject.com/ > length: 96485

Benefits:

  • the UI thread won't be blocked
  • the tasks run in async on seperate threads to the UI
  • the results are in the order of completion, not the order they were executed
  • Feedback is imediate as a task completes giving the user progress feedback

Disadvantages:

  • code is more involved

NOTE: If you have hundreds or thousands of pages that you want to pull down, I have a better ramp up function for not overloading the Threadpool system & CPU.
 
Share this answer
 
v2
Comments
[no name] 4-Mar-19 13:01pm    
the site uses javascript thats the downside.
Graeme_Grant 4-Mar-19 17:43pm    
So you're wanting to do page scraping? the solution above will do what you want to get the page...
[no name] 5-Mar-19 0:40am    
its a single page where you input strings that brings result with javascript
Graeme_Grant 5-Mar-19 1:31am    
You're describing two different issues here:
1. How to download multiple URI in the background - ie: multi-threaded.
2. How to determine how to get the correct data based on the call required

For part 1, still, the above solution will do what you want.

For part 2, you need to do some research... Use Fiddler[^], which is a traffic sniffer, and watch the ajax calls made by the javascript and the responses the server issues ... then you know what URI to call with headers, cookies, etc...
[no name] 5-Mar-19 22:11pm    
i have tried fiddler but didnt get anything meaningful but will try again and let you know the outcome.
Unless you specifically start a new thread, all processing happens on the original - UI - thread. And if you do start additional threads, they cannot directly access any UI components (including WebBrowser controls) without raising a cross threading exception.

Instead of using WebBrowsers and timers, use BackgroundWorker[^] (They are a separate thread, but they make it easy to communicate results to the UI thread via progress / exit events) and use the WebClient class[^] to interact with the webpage in each thread.

If the background threads need to wait for a specific time, you can use Thread.Sleep[^] to do that without needing timers.
 
Share this answer
 
Comments
[no name] 4-Mar-19 12:53pm    
its a nice idea but the setback is that the website i am working with is mainly using javascript to produce results i need extracted thats why i go for webbrowser with its click event.

Another thing is when using timer, you ensure it delivers or initiates the click to bring out the result by including a 'timer1.stop()' at the beginning of the tick event so is this same with backgroundworker? I like the idea really because i could use it to handle webbrowser click event.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900