How to translate this Invoke/Delegate

This forum is meant for questions and discussions about the X# language and tools
ic2
Posts: 1858
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

How to translate this Invoke/Delegate

Post by ic2 »

I still get lost when some code sample uses Invoke & Delegate.

I have this code:

Code: Select all

Self:oEmailDataTable := DataTable{}
Self:oEmailDataTable:Load(Self:oAdsDataReader) 
After usually a few hours I get an exception when a timer based reading + refresh takes place and the DataGrid shows a red cross instead of content. A replier on https://stackoverflow.com/questions/862 ... on-c-sharp says: "At some point you're trying to change the datasource of your datagrid at the exact same time it's painting itself on screen."

His C# sample is:

Code: Select all

dgvComputers1.DataSource = dt;
// Try replacing that by:
this.Invoke(delegate(DataTable table) { dgvComputers1.DataSource = table; }, dt);
I tried

Code: Select all

Invoke({ =>Self:oEmailDataTable:Load(Self:oAdsDataReader)})
but this gives me:

Error    XS1660    Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type  

I tried a few variations (also including Delegate) but I am not sure how to use this.

Can anyone give me the right syntax?

Dick

 
User avatar
Chris
Posts: 4936
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

How to translate this Invoke/Delegate

Post by Chris »

Hi Dick,

If I have understood it correctly, the c# code is defining a delegate type "on the fly" for which there is no syntax currently in X#, but defining the delegate separately should work
(following should be in two lines):

Code: Select all

DELEGATE LoadDelegate(table AS DataTable) AS VOID ... SELF:Invoke((LoadDelegate) {table AS DataTable => SELF:oEmailDataTable:Load(SELF:oAdsDataReader) })
or it should be possible to also do it without defining the delegate type, by using the predefined System.Action generic delegate:

Code: Select all

SELF:Invoke((System.Action ) {table AS DataTable => SELF:oEmailDataTable:Load(SELF:oAdsDataReader) })
 
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
ic2
Posts: 1858
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

How to translate this Invoke/Delegate

Post by ic2 »

Hello Chris,

Thanks for your suggestions. Unfortunately, it doesn't compile:

The first line gives this error:

Severity    Code    Description    Project    File    Line    Suppression State
Error    XS1593    Delegate 'System.Action' does not take 1 arguments 

No idea what I should do to solve that.

The second line goes wrong at the line


Severity    Code    Description    Project    File    Line    Suppression State
Error    XS1003    Syntax error, 'END NAMESPACE' expected   

Severity    Code    Description    Project    File    Line    Suppression State
Error    XS9002    Parser: unexpected input 'Self'   

The self is the self of the 2nd line but if I remove that line it will give the same error on the next line starting with self, so the problem is in the line Delegate LoadDelegate(table As DataTable) As Void    

I am not sure how to change that either....

Dick




 
ic2
Posts: 1858
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

How to translate this Invoke/Delegate

Post by ic2 »

(As the Edit button does not show in the new site I'll add it as a new message: with '2nd line' I mean the 2nd option = the 2 lines)
User avatar
Chris
Posts: 4936
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

How to translate this Invoke/Delegate

Post by Chris »

Hi Dick,

Arghh, the web editor removed again some of the code, trying again:

Code: Select all

 SELF:Invoke((System.Action ) {table AS DataTable => SELF:oEmailDataTable:Load(SELF:oAdsDataReader) }) 
also about the other syntax, you need to put the DELEGATE line in separate place, say before the CLASS declaration
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
User avatar
Chris
Posts: 4936
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

How to translate this Invoke/Delegate

Post by Chris »

Hi Dick,

Ok, this doesn't work, will send you the code by email
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
ic2
Posts: 1858
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

How to translate this Invoke/Delegate

Post by ic2 »

I saw that in my original post I am not "converting" the correct line. Basically this is what happens:

Self:oAdsDataReader := Self:oAdsCommand:ExecuteReader()
Self:oEmailDataTable := DataTable{}
Self:oBindingSource := BindingSource{}
Self:oBindingSource:DataSource := Self:oEmailDataTable
Self:oEmailDataTable:Load(Self:oAdsDataReader)
Self:dataGridViewEmails:DataSource := Self:oBindingSourcea

Apparently, if the line in bold apparently coincides with a Paint call, the program crashes (see call stack below). This can take minutes and sometimes a whole day but it will crash at some point. Instead of solving this, Microsoft programmers have programmed a big red cross to display in where the content of the DataGrid showed and there is no way to rebuild the grid, except restarting, making the project useless. Great.

According to a Stackoverflow post, using Invoke could solve that. Not sure it does, because I have been unable to get this Invoke working in X#. This line:

Self:Invoke((System.Action<DataTable>) {table As DataTable => Self:dataGridViewEmails:DataSource := Self:oEmailDataTable})

(replacing the bold line above) causes an exception Paramater Count mismatch. Chris suggested to add Null:

Self:Invoke((System.Action<DataTable>) {table As DataTable => Self:dataGridViewEmails:DataSource := Self:oEmailDataTable},Null)

But unfortunately that gives the same exception.
Does anyone have a suggestion how to get this working? This is a bit a black box for me and it is also quite frustrating having to spend so much time to fight design flaws in .Net.

Dick

Paint exception:

See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Windows.Forms.DataGridViewImageCell.PaintPrivate(Graphics g, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates elementState, Object formattedValue, String errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts, Boolean computeContentBounds, Boolean computeErrorIconBounds, Boolean paint)
   at System.Windows.Forms.DataGridViewImageCell.Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates elementState, Object value, Object formattedValue, String errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
   at System.Windows.Forms.DataGridViewCell.PaintWork(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
   at System.Windows.Forms.DataGridViewRow.PaintCells(Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, Int32 rowIndex, DataGridViewElementStates rowState, Boolean isFirstDisplayedRow, Boolean isLastVisibleRow, DataGridViewPaintParts paintParts)
   at System.Windows.Forms.DataGridViewRow.Paint(Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, Int32 rowIndex, DataGridViewElementStates rowState, Boolean isFirstDisplayedRow, Boolean isLastVisibleRow)
   at System.Windows.Forms.DataGridView.PaintRows(Graphics g, Rectangle boundingRect, Rectangle clipRect, Boolean singleHorizontalBorderAdded)
   at System.Windows.Forms.DataGridView.PaintGrid(Graphics g, Rectangle gridBounds, Rectangle clipRect, Boolean singleVerticalBorderAdded, Boolean singleHorizontalBorderAdded)
   at System.Windows.Forms.DataGridView.OnPaint(PaintEventArgs e)
   at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
   at System.Windows.Forms.Control.WmPaint(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.DataGridView.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)



 
User avatar
Chris
Posts: 4936
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

How to translate this Invoke/Delegate

Post by Chris »

Hi DIck,

It's not for that line of code that I suggested doing that. For this one, this X# code should work:

Code: Select all

SELF:Invoke((System.Action) { => SELF:dataGridViewEmails:DataSource := SELF:oEmailDataTable})

Code: Select all

but I really doubt this will have an effect on the painting problem you see. Let's hope I am wrong though!
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
ic2
Posts: 1858
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

How to translate this Invoke/Delegate

Post by ic2 »

Hello Chris,

Yes! The line works without the parameter;sorry I started with the wrong line. Thank you so much.

In a while I will know if the paint problem is solved. If I really would not have an idea how to solve this. One would say that there must be more users using the .Net Datagrid and assigning a Datasource to it. I can't imagine that the help file of all the products explain users they have to restart their program at least once a day because their some unsolved issue with painting the grid while assigning a datasource for the last 10 years or so.

Dick
User avatar
Chris
Posts: 4936
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

How to translate this Invoke/Delegate

Post by Chris »

Hi Dick,

But what you are doing is not just assigning a datasource to the grid, but changing the datasource while it is possibly currently using the already assigned one, to update its contents, if I have understood your previous messages (and the stack overflow suggestion that you mentioned) correctly. Why are you assigning the datasource again and again on every tick of a timer? Or is this not what you are really doing? If not, I think it would be much better if you explained exactly what you are doing in detail and show the complete relevant code.
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
Post Reply