if I use the rows preset ID (grid.AddIndex(ID)Wink
and accessing the row by ID (int rownum = grid.Find(rowid, ID); grid.GetRow(rownum))
the program compiles flawlessly but terminates with a runtime error
(I assume the row Id changes during execution since a concurrent thread deletes a row)
it's a sheer PITA to not being able to just grid[rowid].doStuff() with a ficxed rowid not irritated by sortorder or number of rows or position of row on the grid...
// Let us assume that we've defined a Grid object as grid in MyApp; // Then in your worker thread you can call PostCallback(). // Of course you'll need a more complicated version of control code, //WorkerFoo() represents a worker thread function. MyApp::WorkerFoo() { auto rowid = 1; PostCallback( [&] { grid(rowid).DoStuff(); } ); }
The problem (the reason why I went with multithreading in the first place) is still persistent.
the GUI blanks out and the App is irresponsive for quite some time (until all workes are finished)
void MTT::processFile() { int rowc = grid.GetRowCount(); progin.Percent(); // Below is the actual thread function. We are taking advantage of C++11 lambdas here. Thread().Run([=] { for(auto i = rowc - 1, j = 0; i >= 0; i--, j++) { if(IsShutdownThreads()) break; // int q = grid(i, 2); // if(q <= 0) // this->RemoveItem(i, j); // You can also use a dedicated method. PostCallback([=] { grid.Remove(i); progin.Set(j, rowc - 1); }); Sleep(10); } }); }
for(auto i : very_large_vector_to_process) { DoYourStuff(); ProcessEvents(); }
Your example is just what I wanted.. it doesn't explain to me why mine didn't work,
but all I care about now is that it DOES work one way or another Very Happy so I'm good.
void MTT::processFile() { int rowc = grid.GetRowCount(); Vector<bool> del; del.SetCount(rowc, false); progin.SetTotal(rowc); progin.Percent(); for(int i=0; i < rowc; i++) cw & [=, &del] { // Now, this isn't the proper way to accaess shared elements (UI or core) from a // thread. But ONLY in this example, it won't do harm. grid.GetRow(i); int q = grid(i,2); if(q <= 0) // CoWork::FinLock(); del.Set(i, true); }; // cw.Finiehed() // Non blocking way: while(!cw.IsFinished()) ProcessEvents(); for(int i = rowc-1; i>=0; i--) { progin++; if(del[i]) grid.Remove(i); ProcessEvents(); } RDUMP(del); }
for (int i = 0; i < grid.GetCount(); i++) { grid.GetRow(i).Bg(LtGray()); String item = grid(i,5); if (ToUpper(TrimBoth(item)).StartsWith("SHIPPING")) { continue; // skips the SQL query and i gets increased by the for loop } SQL * Select(SqlAll()).From(Whatever).Where(....); if(SQL.Fetch()){//some if then elses again } }
Thread().Run([=] { for (int i = 0; i < grid.GetCount(); i++) { grid.GetRow(i).Bg(LtGray()); String item = grid(i,5); if (ToUpper(TrimBoth(item)).StartsWith("SHIPPING")) { continue; // will be ignored for some reason *SHRUGS* } SQL * Select(SqlAll()).From(Whatever).Where(....); if(SQL.Fetch()){//some if then elses again } } }
if (ToUpper(TrimBoth(item)).StartsWith("SHIPPING")) { grid.Remove(i); i--; continue; }
if (ToUpper(TrimBoth(item)).StartsWith("SHIPPING")) { PostCallback([=] { grid.Remove(i); }); i--; continue; }
MyApp::MyMethod() { String text; // String will be destroyed when when MyMethod returns(). Thread().Run([=] { // Do someting that takes time. text = "hello world"; // This may or may not lead to crash. Because the thread may outlive the text object and MyMethod. }); }
It looks like a concurrency proeblem (a serialization issue) from here. But hard to say...
Are you running multiple worker threads? Is the method where your thread code resides executed more than once?
Or it might be that the worker threads outlive the data objects (grid, or SQL).
For the sake of simplicity I'll give you a minimal example.
The following code MAY or MAY NOT lead to crash, for we can't be sure how long the thread will take to finish.
MyApp::MyMethod() { String text; // String will be destroyed when when MyMethod returns(). Thread().Run([=] { // Do someting that takes time. text = "hello world"; // This may or may not lead to crash. Because the thread may outlive the text object and MyMethod. }); }
So you'll need to take into consideration all kinds of concurrency problems.
If you can provide a simple example (and a very small dummy database) reproducing the crash, I'll loook into it and try to help.
Regards,
Oblivion.
Heap leaks detected:
--memory-breakpoint__ 137368 : Memory at 0x06750290, size 0xA0 = 160
+0 0x06750290 03 00 00 00 97 00 00 00 73 65 6C 65 63 74 20 2A ........select *
+16 0x067502A0 20 66 72 6F 6D 20 4F 55 54 42 20 77 68 65 72 65 from OUTB where
+32 0x067502B0 20 4F 52 44 45 52 49 44 20 3D 20 27 31 32 33 33 ORDERID = '1233
+48 0x067502C0 36 20 50 50 27 20 61 6E 64 20 49 54 45 4D 20 3D 6 PP' and ITEM =
....................
*** TOO MANY LEAKS (274) TO LIST THEM ALL
****************** PANIC: Memory leaks detected! (final check)
Again, thank you,
NOW..
since I just tested your alterations while typing,
I'm still getting memory leaks like crazy *shrugs*
I compiled in MinGW (32bit on the single core and 64bit on the 16core)
You MSVC'd maybe?
outab.cont.GetRow(i).Bg(Yellow());
code not working properly on my machine is that sql conenctions are not exactly thread safe... it's always the SQL causing troubles.
void MTT::ChgColor(int i, RGBA bg) { //outab.cont.GetRow(i).Bg(Yellow()); PostCallback([=] { outab.cont.GetRow(i).Bg(bg); outab.cont.Refresh(); }); }