margarit
asked on
C# - Invoke problem
Hello,
I have the following problem.
I get an attached exception on:
this.Invoke(even, new object[] { buffer }); (line 17)
What do I do wrong?
Please help
Margarit
I have the following problem.
I get an attached exception on:
this.Invoke(even, new object[] { buffer }); (line 17)
What do I do wrong?
Please help
Margarit
delegate void SetSlave(byte[] buffer);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
System.Threading.Thread.Sleep(500);
byte[] buff = new byte[249];
port.Read(buff, 0, 249);
SetSlavesData(buff);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void SetSlavesData(byte[] buffer)
{
if (this.InvokeRequired)
{
SetSlave even = new SetSlave(SetSlavesData);
this.Invoke(even, new object[] { buffer });
}
else
{
int numOfSlaves, sentStrings;
1.JPG
ASKER
Hello,
Thanks for the fast reply.
The declaration of method is: private void SetSlavesData(byte[] buffer)
Buffer is an array. Maybe here is a problem?
THANKS
Thanks for the fast reply.
The declaration of method is: private void SetSlavesData(byte[] buffer)
Buffer is an array. Maybe here is a problem?
THANKS
private void SetSlavesData(byte[] buffer)
{
if (this.InvokeRequired)
{
SetSlave even = new SetSlave(SetSlavesData);
this.Invoke(even, new object[] { buffer });
}
else
{
int numOfSlaves, sentStrings;
numOfSlaves = buffer[1];
sentStrings = buffer[2];
this.slavesTable.Rows.Clear();
this.slavesTable.Rows.Add(numOfSlaves);
}
}
Do I understand this right, you are calling invoke using a delegate to call yourself recursively?
When you hover over the buffer, is it filled? I don't know why, but the error seems to come from somewhere else.
Normally, you do not need to do "new object[] { buffer}", not even with Invoke. I tried it to be sure, but when you use a byte array, it is fine if remove the array constructor:
Just as an example, i dug up a button_click event with a basic version of your code. It runs without errors:
When you hover over the buffer, is it filled? I don't know why, but the error seems to come from somewhere else.
Normally, you do not need to do "new object[] { buffer}", not even with Invoke. I tried it to be sure, but when you use a byte array, it is fine if remove the array constructor:
this.Invoke(even, buffer);
but i'm afraid that all this is not really of any help to resolve your error.Just as an example, i dug up a button_click event with a basic version of your code. It runs without errors:
delegate void TestArrayDelegate(byte[] b_array);
private void Q24344645_Click(object sender, EventArgs e)
{
byte[] myArray = new byte[] {0,1,2};
TestArrayDelegate myFunc= new TestArrayDelegate(DoTestArray);
this.Invoke(myFunc, new object[] {myArray});
// or: this.Invoke(myFunc, myArray);
}
private void DoTestArray(byte[] buffer)
{
Debug.WriteLine(buffer[0]);
}
hi :)
check this
check this
public delegate void SetSlavesDataDelegate(byte[] buffer);
private void SetSlavesData(byte[] buffer)
{
if (this.InvokeRequired)
{
this.Invoke(new SetSlavesDataDelegate(SetSlavesData), buffer);
}
else
{
int numOfSlaves, sentStrings;
numOfSlaves = buffer[1];
sentStrings = buffer[2];
this.slavesTable.Rows.Clear();
this.slavesTable.Rows.Add(numOfSlaves);
}
}
i sow now that you probably have delgate with other name so:
this will work..
this will work..
public delegate void SetSlave(byte[] buffer);
private void SetSlavesData(byte[] buffer)
{
if (this.InvokeRequired)
{
this.Invoke(new SetSlave(SetSlavesData), buffer);
}
else
{
int numOfSlaves, sentStrings;
numOfSlaves = buffer[1];
sentStrings = buffer[2];
this.slavesTable.Rows.Clear();
this.slavesTable.Rows.Add(numOfSlaves);
}
}
@Cebik, what's the difference between my approach and your approach, or were you just following up on that? Btw, using "new object[]" or not doesn't break the code, strange as it may seem.
so what's wrong with her code?
i writed the same code like her...
but in my code i'm not using "new object[]" and it's working! (checked!)
that's why i writed it..
i writed the same code like her...
but in my code i'm not using "new object[]" and it's working! (checked!)
that's why i writed it..
ok.. i've found the same using in your code now..
so the differents is that i corrected her code not making new correct code
i didn't want to take your points :)
so the differents is that i corrected her code not making new correct code
i didn't want to take your points :)
and.. she is doing this because she is changing properties on a form from different thread..
maybe the problem is that you are getting element index 1 and 2 not 0 and 1..
here is example app based on your..
make new windows application and paste the code..
good luck margarit! :)
maybe the problem is that you are getting element index 1 and 2 not 0 and 1..
here is example app based on your..
make new windows application and paste the code..
good luck margarit! :)
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
DataGridView slavesTable = new DataGridView();
public Form1()
{
InitializeComponent();
slavesTable.Dock = DockStyle.Fill;
slavesTable.Columns.Add("0", "0");
slavesTable.Columns.Add("1", "1");
slavesTable.Columns.Add("2", "2");
this.Controls.Add(slavesTable);
}
public delegate void SetSlave(byte[] buffer);
private void SetSlavesData(byte[] buffer)
{
if (this.InvokeRequired)
{
this.Invoke(new SetSlave(SetSlavesData), buffer);
}
else
{
int numOfSlaves, sentStrings;
//numOfSlaves = buffer[0]; //indexing starting from 0 to elements count -1 !!
numOfSlaves = buffer[1];
sentStrings = buffer[2];
//this.slavesTable.Rows.Clear();
//this.slavesTable.Rows.Add(numOfSlaves);
this.slavesTable.Rows.Add(buffer[0], buffer[1], buffer[2]);
}
}
private void Form1_Load(object sender, EventArgs e)
{
Thread nt = new Thread(new ThreadStart(Thread1));
nt.Start();
}
private void Thread1()
{
Random rnd = new Random();
while(true)
{
Thread.Sleep(1000);
byte[] buffer = new byte[] { Convert.ToByte(rnd.Next(0, 255)), Convert.ToByte(rnd.Next(0, 255)), Convert.ToByte(rnd.Next(0, 255)) };
SetSlavesData(buffer);
}
}
}
}
No problem, it just looked a bit strange. Sorry for fuzzing about it...
Btw, as you noticed, this is apparently about cross-thread calls. I am wondering about the error, though. It mentions a parameter "count" which isn't there and is apparently wrong. I don't see that parameter on the place of the error. Is the error really occurring on that point, or at a deeper level, which is somehow hidden for the debugger?
Btw, as you noticed, this is apparently about cross-thread calls. I am wondering about the error, though. It mentions a parameter "count" which isn't there and is apparently wrong. I don't see that parameter on the place of the error. Is the error really occurring on that point, or at a deeper level, which is somehow hidden for the debugger?
that's right..
it must be somwhere else..
she must give us stack trace..
i've checked this.. and both of this is working..
it must be somwhere else..
she must give us stack trace..
i've checked this.. and both of this is working..
this.Invoke(myFunc, new object[] {myArray});
this.Invoke(myFunc, myArray);
(if you don't want to know the whole story behind it, or how to keep this from happening in the future, just read the bold lines below)
The error
I think, Cebik, that you are on the right page there. The buffer is, of course, indexed from zero. But the error received is not about IndexOutOfRangeException (see screenshot 1), but about an ArgumentOutOfRangeExceptio n. I was puzzled by that, because there seemed to be no call where that actually happened.
The count param
Until my eye was caught by the Rows.Add(count) method. That was where the "count" parameter was! Assuming that slavesTable was a DataGridView I tried to mimic the situation again and this time I succeeded.
Not the right line
My last comment, about the error taking place somewhere else, was apparently correct. See the second screenshot. The Visual Studio Debugger is not capable of diving into the queued method (see http://weblogs.asp.net/justin_rogers/pages/126345.aspx for what happens under the hood) and shows the line where the Invoke takes place.
How to debug
So, how could you actually debug this correctly? Quite simply: put a breakpoint at the beginning of the method (just after the "else") that is being invoked and you can step through it with F10.
How to solve
How to solve it? Possibly by following up on Cebik's advice: maybe you have the wrong index. Or maybe you didn't want to use the data in the buffer at all as count for adding rows (as Cebik suggests) and you just want to add the contents of the buffer.
The code that Cebik shows you will add three cells in one new row.
The code that you had originally, will add buffer[1] amount of rows. Because buffer[1] was holding zero or a negative value, you got the error you saw.
Now you know what is actually going on, you know how to solve it, to debug it and how to display it.
-- Abel --
ScreenShot232.png
ScreenShot231.png
The error
I think, Cebik, that you are on the right page there. The buffer is, of course, indexed from zero. But the error received is not about IndexOutOfRangeException (see screenshot 1), but about an ArgumentOutOfRangeExceptio
The count param
Until my eye was caught by the Rows.Add(count) method. That was where the "count" parameter was! Assuming that slavesTable was a DataGridView I tried to mimic the situation again and this time I succeeded.
Not the right line
My last comment, about the error taking place somewhere else, was apparently correct. See the second screenshot. The Visual Studio Debugger is not capable of diving into the queued method (see http://weblogs.asp.net/justin_rogers/pages/126345.aspx for what happens under the hood) and shows the line where the Invoke takes place.
How to debug
So, how could you actually debug this correctly? Quite simply: put a breakpoint at the beginning of the method (just after the "else") that is being invoked and you can step through it with F10.
How to solve
How to solve it? Possibly by following up on Cebik's advice: maybe you have the wrong index. Or maybe you didn't want to use the data in the buffer at all as count for adding rows (as Cebik suggests) and you just want to add the contents of the buffer.
The code that Cebik shows you will add three cells in one new row.
The code that you had originally, will add buffer[1] amount of rows. Because buffer[1] was holding zero or a negative value, you got the error you saw.
Now you know what is actually going on, you know how to solve it, to debug it and how to display it.
-- Abel --
ScreenShot232.png
ScreenShot231.png
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
i was thinking about this rows.add also but i was almoust sleep yesterday..
glories for you ;)
glories for you ;)
ASKER
THANKS A LOT
Btw, you say "Invoke" but this is not a typical Invoke/Reflection question, correct? Can you show the body of Invoke?