Computer Hope

Software => Computer programming => Topic started by: DaftHacker on October 11, 2013, 02:43:29 AM

Title: [Help] C# WPF Dispatcher.Invoke (threading)
Post by: DaftHacker on October 11, 2013, 02:43:29 AM
Im trying to use dispatcher.invoke on an if statement to check if a website can work. I keep getting the thread usage warning. Is there any way to fix this ? I am Currently not good with background workers or threading with wpf.

I am going to use a loop with this code and have it be used in a thread so when someone pastes a new website to check it wont lag out the program while entering text
Code: [Select]
        public void CheckOnline()
        {
            try
            {
                if (wc.DownloadString(website_1.Text) == "")
                {
                    Dispatcher.Invoke(new Action(() => status_1.Foreground = Elysium.AccentBrushes.Red));
                    Dispatcher.Invoke(new Action(() => status_1.Content = "Not Working"));
                }
                else
                {
                    Dispatcher.Invoke(new Action(() => status_1.Foreground = Elysium.AccentBrushes.Green));
                    Dispatcher.Invoke(new Action(() => status_1.Content = "Working"));
                }
            }
            catch
            {
                Dispatcher.Invoke(new Action(() => status_3.Foreground = Elysium.AccentBrushes.Red));
                Dispatcher.Invoke(new Action(() => status_3.Content = "Error"));
            }
            try
            {
                if (wc.DownloadString(website_2.Text) == "")
                {
                    Dispatcher.Invoke(new Action(() => status_2.Foreground = Elysium.AccentBrushes.Red));
                    Dispatcher.Invoke(new Action(() => status_2.Content = "Not Working"));
                }
                else
                {
                    Dispatcher.Invoke(new Action(() => status_2.Foreground = Elysium.AccentBrushes.Green));
                    Dispatcher.Invoke(new Action(() => status_2.Content = "Working"));
                }
            }
            catch
            {
                Dispatcher.Invoke(new Action(() => status_3.Foreground = Elysium.AccentBrushes.Red));
                Dispatcher.Invoke(new Action(() => status_3.Content = "Error"));
            }
            try
            {
                if (wc.DownloadString(website_3.Text) == "")
                {
                    Dispatcher.Invoke(new Action(() => status_3.Foreground = Elysium.AccentBrushes.Red));
                    Dispatcher.Invoke(new Action(() => status_3.Content = "Not Working"));
                }
                else
                {
                    Dispatcher.Invoke(new Action(() => status_3.Foreground = Elysium.AccentBrushes.Green));
                    Dispatcher.Invoke(new Action(() => status_3.Content = "Working"));
                }
            }
            catch
            {
                Dispatcher.Invoke(new Action(() => status_3.Foreground = Elysium.AccentBrushes.Red));
                Dispatcher.Invoke(new Action(() => status_3.Content = "Error"));
            }
            try
            {
                if (wc.DownloadString(website_4.Text) == "")
                {
                    Dispatcher.Invoke(new Action(() => status_4.Foreground = Elysium.AccentBrushes.Red));
                    Dispatcher.Invoke(new Action(() => status_4.Content = "Not Working"));
                }
                else
                {
                    Dispatcher.Invoke(new Action(() => status_4.Foreground = Elysium.AccentBrushes.Green));
                    Dispatcher.Invoke(new Action(() => status_4.Content = "Working"));
                }
            }
            catch
            {
                Dispatcher.Invoke(new Action(() => status_4.Foreground = Elysium.AccentBrushes.Red));
                Dispatcher.Invoke(new Action(() => status_4.Content = "Error"));
            }
        }
Title: Re: [Help] C# WPF Dispatcher.Invoke (threading)
Post by: BC_Programmer on October 11, 2013, 06:02:41 AM
well you could remove ALL the invokes and surround the body in a single Invoke call.

Title: Re: [Help] C# WPF Dispatcher.Invoke (threading)
Post by: DaftHacker on October 11, 2013, 06:15:35 AM
well you could remove ALL the invokes and surround the body in a single Invoke call.
How would i do that ? I really suck at using wpf, i only use it for making nice looking apps.
Title: Re: [Help] C# WPF Dispatcher.Invoke (threading)
Post by: BC_Programmer on October 11, 2013, 10:07:25 PM
WPF has nothing to do with the threading solution, FWIW. I've used WPF once, but I've used the WebClient extensively.

I was going to stick exactly what I mentioned (just coalesce it into one invoke). But then I noticed the repetition, as well as the use of DownloadString(), and separated them out.

This version is not tested but should work excepting minor oversights:

Code: [Select]
public void CheckOnline()
        {
           String[] Websites = new String[]{website_1.Text,website_2.Text,website_3.Text,website_4.Text};
           StatusBar[] StatBars = new StatusBar[]{status_1,status_2,status_3,status_4}

           for(int i=0;i<Websites.Length;i++){
               String site = Websites[i];
               StatusBar statbar = StatBars[i];
               String TempFileUse = Path.GetTempFileName();
               WebClient useClient = new WebClient();
               useClient.DownloadFileCompleted+=(s,e)=>{
               Dispatcher.Invoke(()=>{
                   if(e.Error!=null){
                       statbar.Foreground = Elysium.AccentBrushes.Red;
                       statbar.Content = "Not Working";
                   }
                   else {
                       statbar.Foreground = Elysium.AccendBrushes.Green;
                       statbar.Content = "Working";
                   
                   }
                   File.Delete(TempFileUse);
               })};
               useClient.DownloadFileAsync(site,TempFileUse);
               
               }
           
        }

Basically it just combines each test, since each one simply uses a different status bar and a different website, those are gathered into corresponding arrays. Then the array is iterated over and with each one a new WebClient is created. the DownloadCompleted event is set to the appropriate code to set the color and text, using the EventArgs passed in to determine if an Error occurred, and then delete the temporary file; the WebClient's DownloadFileAsync is then called.

Note that each event handler uses Invoke() with multiple-line arguments (in fact, I use multi-line lambda's more than once).

If CheckOnline itself is running in another thread (why?) then the initialization logic for the arrays will need to be within a similar Invoke lambda.
Title: Re: [Help] C# WPF Dispatcher.Invoke (threading)
Post by: Cagatey01 on December 23, 2014, 03:49:10 AM
need help in creating a batch with below conditions.
i have abc.txt file. i want to read this file and load header and trailer information in xyz.txt file. and i want to accoplish this using batch file.
can you please help me in this