GridView Exception: reentrant call to the SetCurrentCellAddressCore function

M

Martin B

Hallo to everyone!

Problem:
--------
GridView Exception: reentrant call to the SetCurrentCellAddressCore function

System:
-------
WinXP Professional, english, .NET Framework 2.0 Beta Language C#

Simplified Architecture of my Porgram:

2 Forms:
--------
- MainForm
- DetailForm

2 Threads:
----------
- Main Thread which runs the MainForm //Application.Run(MainForm)
- Telegram Thread //receiving Socket Data for visualization

Scenario:
---------
Telegram Thread receives frequently (2s) socket data which forces the
Main Thread via Callback 'Visualization' to refresh the Data in
the GridView. Within the Callback function 'Visualization' the
Telegram Thread could return immediately, doing his job, by calling
this.Invoke(new VisualDelegate(MainFormVisual)).
'MainFormVisual' wires up the GridView.DataSource with a DataTable,
which is stored offline in memory, as shown in the following lines

1. gvMyGridView.DataSource = null;
2. gvMyGridView.DataSource = BuildActData(); //returning a DataTable

After a undifined and non reproduceable timespan (approx. 20 min)
repating this scenario, the following Exception will be thrown at line 1:
EXCEPTION: Operation is not valid because it results in a reentrant call to
the SetCurrentCellAddressCore function.

Thank you for every advice, bugfix or workaround

Martin
 
C

cody

when calling this.Invoke() are your sure that "this" and "gvMyGridView" runs
in the same thread? if not use gvMyGridView.Invoke().
 
M

Martin B

Hallo Cody!

Thanx for your quick reply and I'm sorry for the inconvenience in my
description.
It would be better to recommend that with this.Invoke I mean
MainForm.Invoke, and MainForm is
the owner which created gvMyGridView.

I also read plenty of MSDN-documents on topics about Control.Invoke and
Delegate.Invoke, where I found
out that Control.Invoke processes the given Delegate on the underlying
Thread which created the Control (in my case
it is the Main-Thread. I understood it that way, that with a Control.Invoke
an implicit SendMessage is called to the win32 Message-Queue of my MainForm.
(To be pecisely Now I use a Control.BeginInvoke -implicitely PostMessage-
for async calls, instead).
On the other hand Delegate.Invoke/BeginInvoke executes the Delegate on the
next availeable thread on the Thread-Pool.
So for me it sounds that my call will be queued into the Message-Queue of
MainForm by my Socket-Thread, and dequeued by the Main-Thread to be
processed sequential (not like Delegate.BeginInvoke where parallel
processing is possible).

Maybe now you could understand why I'm really wondering about an exception
about REENTRANCY - I can not see a circumstance on my side where two threads
try to call any code section concurrently.

Maybe there is somthing wrong with my way of DataBinding, but in Beta 1 it
worked fine!

hope for any suggestions!

bye

martin
 
Joined
Aug 31, 2006
Messages
2
Reaction score
0
I have the samilor problem,but I resolved it;
1. Do not remove the row you want to remove directly,just store it in an array;
Codes are like below:
private int[] delIndex = null;
pushDelIndex(row.CurrentRow.Index);
private void pushDelIndex(int _index){
if(delIndex==null){
delIndex=new int[]{_index};
}else{
Array.Resize(ref delIndex,delIndex.Length+1);
delIndex[delIndex.Length - 1] = _index;
}
}
2. Then open a thread when the program start;
Codes are like below:
Thread delTh = new Thread(new ThreadStart(delRowThread));
delTh.Start();
3. Use the thread to check the array delIndex every 100 millsecondsCif it is not null,the call the function delRow;
Codes are like below:
void delRowThread() {
while (delFlag) {
if (delIndex != null) {
if (deling == false)
{
delRow();
}
}
Thread.Sleep(100);
}
}
private delegate void delRowCallBack();
void delRow() {
if (PlayList.InvokeRequired)
{
deling = true;
delRowCallBack o = new delRowCallBack(delRow);
this.Invoke(o);
}
else {
for (int i = 0; i < delIndex.Length; i++) {
PlayList.Rows.RemoveAt(delIndex);
}
deling = false;
delIndex = null;
}
}


Martin B said:
Hallo to everyone!

Problem:
--------
GridView Exception: reentrant call to the SetCurrentCellAddressCore function

System:
-------
WinXP Professional, english, .NET Framework 2.0 Beta Language C#

Simplified Architecture of my Porgram:

2 Forms:
--------
- MainForm
- DetailForm

2 Threads:
----------
- Main Thread which runs the MainForm //Application.Run(MainForm)
- Telegram Thread //receiving Socket Data for visualization

Scenario:
---------
Telegram Thread receives frequently (2s) socket data which forces the
Main Thread via Callback 'Visualization' to refresh the Data in
the GridView. Within the Callback function 'Visualization' the
Telegram Thread could return immediately, doing his job, by calling
this.Invoke(new VisualDelegate(MainFormVisual)).
'MainFormVisual' wires up the GridView.DataSource with a DataTable,
which is stored offline in memory, as shown in the following lines

1. gvMyGridView.DataSource = null;
2. gvMyGridView.DataSource = BuildActData(); //returning a DataTable

After a undifined and non reproduceable timespan (approx. 20 min)
repating this scenario, the following Exception will be thrown at line 1:
EXCEPTION: Operation is not valid because it results in a reentrant call to
the SetCurrentCellAddressCore function.

Thank you for every advice, bugfix or workaround

Martin
 
Joined
Aug 31, 2006
Messages
2
Reaction score
0
Õâ¸öÎÊÌâÖÕÓÚ½â¾öÁË:
²»Ö±½Óɾ³ýÄÇÐÐ,¶øÊÇ°ÑËüѹÈë(´æ·Å)µ½Êý×顪¡ª
private int[] delIndex = null;
pushDelIndex(row.CurrentRow.Index);
private void pushDelIndex(int _index){
if(delIndex==null){
delIndex=new int[]{_index};
}else{
Array.Resize(ref delIndex,delIndex.Length+1);
delIndex[delIndex.Length - 1] = _index;
}
}

³ÌÐò¿ªÊ¼Ê±´ò¿ªÒ»¸öÏ̡߳ª¡ª

Thread delTh = new Thread(new ThreadStart(delRowThread));
delTh.Start();

void delRowThread() {
while (delFlag) {
if (delIndex != null) {
if (deling == false)
{
delRow();
}
}
Thread.Sleep(100);
}
}
´ËÏß³Ìÿ100ºÁÃë¼ì²éÒ»´ÎdelIndex£¬·¢ÏÖËü²»ÎªnullÔòµ÷ÓÃɾ³ýÐеķ½·¨¡ª¡ª
private delegate void delRowCallBack();
void delRow() {
if (PlayList.InvokeRequired)
{
deling = true;
delRowCallBack o = new delRowCallBack(delRow);
this.Invoke(o);
}
else {
for (int i = 0; i < delIndex.Length; i++) {
PlayList.Rows.RemoveAt(delIndex);
}
deling = false;
delIndex = null;
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top