Hey!

I have a problem with my code:

public void UpdateColumn(object stateInformation, int cid = 0, int status = 0)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => UpdateColumn(stateInformation, cid, status)));
            }
            else
            {
                if (status == 0)
                {
                    var res = "Failed";
                    listView1.Items[cid].SubItems.Add(res);

                }
                else if (status == 1)
                {
                    var res = "Successful";
                    listView1.Items[cid].SubItems.Add(res);
                }
            }
        }


        public void DoChecking(object iid)
        {
            var lid = Convert.ToInt32(iid);

            var file = openFileDialog1.FileName;
            StreamReader read = new StreamReader(file);
            var links = read.ReadToEnd();

            string[] urls = links.Split('\n');

            if (CheckExist(urls[lid]))
            {
                success++;
                ShowSuccessful();
                UpdateColumn("", lid, 1);
            }
            else
            {
                failed++;
                ShowFailed();
                UpdateColumn("", lid, 0);
            }

            var total = failed + success;
            UpdateTotalCounter(total);           
        }

I did some testing and I can see that :

Invoke(new Action(() => UpdateColumn(stateInformation, cid, status)));

is failing. Can you please help me ?

Recommended Answers

All 21 Replies

Take a look into this example, which invokes the label:

public partial class Form1 : Form
    {
        delegate void MyDelegate(string msg);
        public Form1()
        {
            InitializeComponent();
            labelShow.Text = "";
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ThreadStart(DoingTimeConsumingStuff));
            thread.Start();
        }

        private void DoingTimeConsumingStuff()
        {
            for (decimal i = 0.0001M; i < 1000000000; i++)
            {
                UpdatingMyControl(i.ToString());
            }
        }

        private void UpdatingMyControl(string strValue)
        {
            if (this.labelShow.InvokeRequired)
                this.labelShow.Invoke(new MyDelegate(UpdatingMyControl), new object[] { strValue });
            else
                labelShow.Text = strValue;
        }      
    }

The () => UpdateColumn(stateInformation, cid, status) uses a lambda expression to create a delegate signature for your UpdateColumn void function, but does not 'passes' the parameters to it when invoked.

Probably you need to change your sentence to some thing like:

Invoke(new Action(() => UpdateColumn(stateInformation, cid, status)), new object[] {stateInformation, cid, status});

Hope this helps

Sorry no mate, somehow it doesn't work.. no errors, but program will crash after checking all links.

I woud suggest you to split the sentence.

1) declare the delegate at class level

delegate void UpdateColumnDelegate(object stateInformation, int cid, int status)

2) instad of

if (InvokeRequired){Invoke(new Action(() => UpdateColumn(stateInformation, cid, status)));}

try this untested code

if (InvokeRequired){ var TheDelegate = new UpdateColumnDelegate
(UpdateColumn); object[] params = {stateInformation, cid, status}; {Invoke(TheDelegate, params); }....

This way you can verify step by step what is ongoing. Then see what is happening.

Hope this helps.

Hey!

Somehow it doesnt want to work :/

Here's my code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {

        delegate void UpdateColumnDelegate(object stateInformation, int cid, int status);
        public static int failed;
        public static int success;
        public static string pattern;
        public static int id = 0;
        public static string url;
        public static bool status;

        public Form1()
        {
            InitializeComponent();
            UpdateTotalCounter();
            ShowSuccessful();
            ShowFailed();
        }

        private void LoadLinks(string path)
        {
            StreamReader read = new StreamReader(path);
            var items = read.ReadToEnd();

            string[] item = items.Split('\n');

            foreach (string i in item)
            {

                listView1.Items.Add(i);

            }

            UpdateTotalCounter();
        }

        private void UpdateTotalCounter(int trace = 0)
        {

            var itemscount = listView1.Items.Count;

            if (itemscount == 0)
            {
                toolStripStatusLabel1.Text = "Checked links: 0 out of 0";
            }
            else
            {
                toolStripStatusLabel1.Text = "Checked links: " + trace + " out of " + listView1.Items.Count;
            }

        }

        public void ShowSuccessful()
        {
            if (toolStripStatusLabel2.Text == "")
            {
                toolStripStatusLabel2.Text = "Success: 0";
            }
            else
            {
                toolStripStatusLabel2.Text = "Success: " + success.ToString();
            }
        }

        public void ShowFailed()
        {
            if (toolStripStatusLabel3.Text == "")
            {
                toolStripStatusLabel3.Text = "Failed: 0";
            }
            else
            {
                toolStripStatusLabel3.Text = "Failed: " + failed.ToString();
            }
        }

        public bool CheckExist(string item)
        {
            if (item != null)
            {
                var replace = Regex.Replace(item, "http://", "");
                HttpWebRequest WebRequestObject = (HttpWebRequest)HttpWebRequest.Create(item);
                WebResponse Response = WebRequestObject.GetResponse();
                Stream WebStream = Response.GetResponseStream();
                StreamReader Reader = new StreamReader(WebStream);
                string PageContent = Reader.ReadToEnd();
                Reader.Close();
                WebStream.Close();
                Response.Close();

                Match match = Regex.Match(PageContent, replace);

                if (match.Success)
                {
                    status = false;
                }
                else
                {
                    status = true;
                }               

            }

            return status;
            
        }

        public void DoChecking(object iid)
        {
            var lid = Convert.ToInt32(iid);

            var file = openFileDialog1.FileName;
            StreamReader read = new StreamReader(file);
            var links = read.ReadToEnd();

            string[] urls = links.Split('\n');

            if (CheckExist(urls[lid]))
            {
                success++;
                ShowSuccessful();
                UpdateColumn("", lid, 1);
            }
            else
            {
                failed++;
                ShowFailed();
                UpdateColumn("", lid, 0);
            }

            var total = failed + success;
            UpdateTotalCounter(total);           
        }

        public void Run()
        {
            var num = numericUpDown1.Value;
            var item_c = listView1.Items.Count;

            Thread[] array = new Thread[item_c];
            for (int i = 0; i < array.Length; i++)
            {
                ParameterizedThreadStart start = new ParameterizedThreadStart(DoChecking);
                array[i] = new Thread(start);
                array[i].Start(i);
            }

            for (int i = 0; i < array.Length; i++)
            {
                array[i].Join();
            }

        }

        public void End()
        {
            button1.Enabled = true;
            button2.Enabled = true;
            button3.Enabled = true;
            button4.Enabled = true;
            button5.Enabled = true;
            button6.Enabled = true;

            MessageBox.Show("Ended!");
        }

        public void UpdateColumn(object stateinformation, int cid, int status)
        {
            if(this.listView1.InvokeRequired) {

                var TheDelegate = new UpdateColumnDelegate(UpdateColumn); 
                object[] items = { stateinformation, cid, status };
                this.listView1.Invoke(TheDelegate, items);

            }

            if (status == 0)
            {
                var res = "Failed";
                listView1.Items[cid].SubItems.Add(res);
            }
            else if (status == 1)
            {
                var res = "Successful";
                listView1.Items[cid].SubItems.Add(res);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            listView1.Columns.Add("Link", 372, HorizontalAlignment.Left);
            listView1.Columns.Add("Status", 125, HorizontalAlignment.Left);            
        }

        private void button1_Click(object sender, EventArgs e)
        {
            openFileDialog1.Title = "Open links list";
            openFileDialog1.FileName = "";
            openFileDialog1.Filter = "Text File|*.txt";
            openFileDialog1.ShowDialog();

            var filename = openFileDialog1.FileName;

            if (filename != "")
            {
                LoadLinks(filename);
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            openFileDialog2.Title = "Open patterns list";
            openFileDialog2.FileName = "";
            openFileDialog2.Filter = "Text File|*.txt";
            openFileDialog2.ShowDialog();

            pattern = openFileDialog2.FileName;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            button4.Enabled = false;
            button6.Enabled = false;
            button2.Enabled = false;
            button3.Enabled = false;
            numericUpDown1.Enabled = false;

            Run();
        }
    }
}

Can somebody please check it, what's wrong with it.

There are two things you can do to check.

1. If the delegate is "crashing" then it's generally something in the method that's throwing the exception. Place a breakpoint on line 192 of the code you pasted above and follow the code execution. See if any exceptions are thrown.

2. You're calling the invoke on the listView control. Try calling it on the form itself.
Instead of if(this.listView1.InvokeRequired) and this.listView1.Invoke(TheDelegate, items); Use if(this.InvokeRequired) and this.Invoke(TheDelegate, items);

Hm.. this breakpoint doesnt do anything also i tried all your methods, but they don't work :/

If the breakpoint isn't stopping the application, your delegate is never actually called.

Can you copy and paste the exception message please when your delegate fails (from your original code without my modifications)

EDIT: Also I just noticed. You need to return; from the method after your delegate call. Otherwise you will try and run the code below it and fail (cross-threaded operation)

Hey!

I tried this return, but somehow it still doesn't do anything. but here's the error:

Cross-thread operation not valid: Control 'listView1' accessed from a thread other than the thread it was created on.

It is the problem I thought for number 2 ;)

Change this...

if(this.listView1.InvokeRequired)
{
    var TheDelegate = new UpdateColumnDelegate(UpdateColumn);
    object[] items = { stateinformation, cid, status };
    this.listView1.Invoke(TheDelegate, items);
}

to this:

if(this.InvokeRequired)
{
    UpdateColumnDelegate TheDelegate = new UpdateColumnDelegate(UpdateColumn);
    object[] items = { stateinformation, cid, status };
    this.Invoke(TheDelegate, items);
    return;
}

Then tell me what exception you get, if any.

Sorry.. still nothing. It doesn't show any error. It just runs code.. and then crashes.

If it's crashing, you should be getting an exception. Visual Studio very rarely "just crashes".

Can you put a break point on the if(status == 0) line and step through it?

http://i53.tinypic.com/w2jfb6.jpg

please look @ that picture.. there you can see that it just crashed. I can't close it or move my window.. anything.

alos I run just F5.. is there any other way to run that script ? Maybe there's a problem

Use F10 or F11 to run step by step (step through / step in).

Also you can set 'break points' selecting the line to stop executing and pressing F9. From this point you can go step by step by F11 or resume the execution by F5.

Watch the Debug options.

Hope this helps

I have found the problem.

In the Run() method, you are creating threads to run the task. This is fine. You then start the threads. This is fine. You then go to join the threads, which is, to wait until they're finished. 165. array[i].Join(); This is *usually* fine...

This is until you realise that you're trying to post back to the main UI thread on your Invoke. This is why the break point is never hit. Your program is in deadlock.

The deadlock is between the Join, which requires your program to wait until the thread finishes. But the thread cannot finish without without posting back onto your UI thread (the thread which is currently waiting for the Join method to complete). So you have two threads, now waiting for each other to finish.

This is deadlock.

Hmmm.. okay, but how to fix it ?

Well, I'm afraid this is something you need to work out yourself which is better ^^

One idea is to push it all into a separate class. Have all the work processed and stored there. When it's finished, update it on the form.

Another is to push the run method onto a different thread and start that thread, but don't wait for the Join. Just "hit and run" so to speak.

The "best" method, would be to create a processing class. Which does all the work, and lets you retrieve the results. The quick and dirty method, is to push Run() onto its own thread, start it and don't wait for it with join.

OMG, I removed that join thing.. and it works perfectly :D awesome:D

I didn't know if it was a requirement or not, so I didn't suggest it. But glad it's sorted.

Hm, now I'm thinking.. how to stop everything when all threads are finished.
I'm sorry I'm pretty new to C# :D

A return should do.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.