1

I've been googling around and trying some different approaches but none of them is working.

Using an anti-cross-thread function to return a value

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

C# Return value from function invoked in thread

http://www.dreamincode.net/forums/topic/188209-cross-thread-calls-made-easy/

My code (very briefly) is the following:

public partial class print : Form {

    ListView _listOfCategories = new ListView();
    delegate string getNameOfPrinterCallBack(string name);

     private string getNameOfPrinter(string name){
        ListViewItem search = new ListViewItem();

        if (this._listOfCategories.InvokeRequired)
        {
            getNameOfPrinterCallBack cb = new getNameOfPrinterCallBack(getNameOfPrinter);

            return (string)Invoke(cb, new object[] { name });
        }
        else {

            search = this._listOfCategories.FindItemWithText(name, false, 0);

            return this._listOfCategories.Items[search.Index].SubItems[1].Text;
        }
    }
}

And I call the function getNameOfPrinter in a timer (5 in 5 seconds). The first time it works properly, the second time and further it starts giving me the error:

An unhandled exception of type 'System.StackOverflowException' occurred in System.Windows.Forms.dll

The line that prints the error is return (string)Invoke(cb, new object[] { name });

This happens because I'm trying to implement a way of avoid the error of Cross Threading. What am I doing wrong with my code?

Community
  • 1
  • 1
Linesofcode
  • 5,327
  • 13
  • 62
  • 116
  • As soon as `this._listOfCategories.InvokeRequired` evaluates to true you go into infinite recursion because you keep running `getNameOfPrinterCallBack(getNameOfPrinter)`. It is not clear why you are doing this, at first glance it looks like you should be doing the same thing you do in the else, just via a delegate. – Ben Robinson Dec 12 '14 at 10:16
  • You're right. I googled about that and I'm stuck into a infinite recursion. What do you suggest? My only goal with this is to avoid cross threading and return the properly String. – Linesofcode Dec 12 '14 at 10:19
  • 1
    You are using the wrong kind of Timer class. Make it a System.Windows.Forms.Timer and you can stop fighting the machine. There is no point to, say, System.Timers.Timer, you are invoking anyway. Nothing but grief. – Hans Passant Dec 12 '14 at 10:24

2 Answers2

1

You are going into an infinite loop when this._listOfCategories.InvokeRequired evaluates to true (you are currently recalling yourself at that point, and InvokeRequired will always be true).

Change your pattern to something like below, which should help:

    private void OnSomeTimerEvent(object sender, EventArgs e)
    {
        Action action = new Action(() =>
        {
            // Do your UI control item processing here. Don't recall this method!
        });

        if (this.InvokeRequired)
        {
            // or Use BeginInvoke if you don't want the caller to block (post the message 
            // onto the UI's message pump and will get processed asynchronously).
            this.Invoke(action);
        }
        else
        {
            action();
        }
    }
Gusdor
  • 14,001
  • 2
  • 52
  • 64
Jeb
  • 3,689
  • 5
  • 28
  • 45
0

Solved.

if (this._listOfCategories.InvokeRequired)
{
    getNameOfPrinterCallBack cb = new getNameOfPrinterCallBack(getNameOfPrinter);

    return (string)this._listOfCategories.Invoke(cb, name);
}
else {

    search = this._listOfCategories.FindItemWithText(name, false, 0);

    return this._listOfCategories.Items[search.Index].SubItems[1].Text;
}
Linesofcode
  • 5,327
  • 13
  • 62
  • 116