Author Topic: Transaction within a loop.  (Read 9371 times)

0 Members and 1 Guest are viewing this topic.

BillZndl

  • Guest
Re: Transaction within a loop.
« Reply #15 on: September 24, 2014, 04:56:25 PM »
I have no problems using Database(false, true) constructor and the only time I have to lock the document when updating a side database is using 
Database(false, false) from Application context.
 
So if  Database(false, false)  used from a modeless dialog or a command with CommandFlags.Session then I have to lock document.

After un-defining the open command in my s::startup,

I initiate and instance of my modeless dialog with this command method:

Code - C#: [Select]
  1.  
  2. [CommandMethod("open", CommandFlags.Session)]
  3.        
  4.         public static void ShowDialogForm()
  5.         {
  6.             Autodesk.AutoCAD.ApplicationServices.Application.ShowModelessDialog(LundFileDialog.Instance);
  7.         }
  8.  

Then with a button on that dialog, I initiate a second modeless dialog instance and hide the first:

Code - C#: [Select]
  1. private void button7_Click(object sender, EventArgs e)
  2.         {          
  3.             AcadApp.ShowModelessDialog(DrawingSearchDialog.Instance);
  4.         }
  5.  

From there I run the code for searching and replaceing text in drawings using a button click.
The search thread is supposed to run on another thread from a control so it doesn't lock up the UI.
The search & replace is simply run on the main thread as i don't use it that often.
I removed the document lock from the search & replace and use:
Code - C#: [Select]
  1. using (Database database = new Database(false, false))
  2.                 {
  3.                     database.ReadDwgFile(str, FileOpenMode.OpenForReadAndWriteNoShare, false, "");
  4.                     database.CloseInput(true);
  5.  
  6.                     using (Transaction transaction = database.TransactionManager.StartTransaction())
  7.  
I replace parts of strings and then run database.SaveAs(database.Filename, DwgVersion.Current); with no document lock.

I'll play some more tommorrow, I see I still have the document lock in the search only block.
Like I said, all examples talked like false, true should work with out the doc lock but I've hit the limit of my knowlege on the subject.



nekitip

  • Guest
Re: Transaction within a loop.
« Reply #16 on: September 25, 2014, 02:34:26 AM »
I have not read the whole tread since I find it hard to concentrate in the morning :D, but just as a thought since i saw this:
Quote
From there I run the code for searching and replaceing text in drawings using a button click.
The search thread is supposed to run on another thread from a control so it doesn't lock up the UI.
And the short comment (again, I have not read whole tread) is that the multithreading is not working in autocad and will not be supported any time soon (as per Stephen Preston), so EVERYTHING you do in autocad must be in the same thread, and the only thing you can do the multithreaded way, is to extract data from dbobjects you need in the main tread, and move only that data in different thread, continue with main UI, and when finished, move results back. Now, this is easy in .NET 4.5, with Await, Asyinc .NET commands, but that is 4.5 is acad2015 only for now.

Also, when returning data, remember to check if editor is still looking at the same mdicurrent document (or doc at all)

BillZndl

  • Guest
Re: Transaction within a loop.
« Reply #17 on: September 25, 2014, 07:05:43 AM »
Jeff,
It does work as you said when I remove the doc lock, and use the new side database for the transaction and ReadDwgFile(false, true,.
I was hoping to get away from starting a transaction each time through the loop but it appears to me that, to do it right, I'll have to do just that.
Code - C#: [Select]
  1. for (int i = 0; i < listBox2.Items.Count; i++)
  2.                     {
  3.                         SetProgBarStatus(i);
  4.  
  5.                         string str = listBox2.Items[i].ToString();
  6.  
  7.                         using (Database database = new Database(false, true))
  8.                         {                                
  9.                             database.ReadDwgFile(str, FileOpenMode.OpenForReadAndAllShare, false, "");
  10.                             using (Transaction transaction = database.TransactionManager.StartTransaction())
  11.                             {
  12.  


@ nekitip,
Thanks!
That explains a lot of things to me, that I was fighting with last week.

The only reason I tried to run something on another thread,
was to keep the UI from "appearing to lock up" while a file search was going on.
Don't know if I accomplished running on a different thread
but by using the methods I found HERE:
the search can run now and the dialog doesn't display the swirly Cursor and the screen going white.

I even managed to run a progress bar that looks like it's in sync with the search.





MexicanCustard

  • Swamp Rat
  • Posts: 705
Re: Transaction within a loop.
« Reply #18 on: September 25, 2014, 07:54:50 AM »
The only time I use a Document Lock is when working with databases open in the editor, never for a side database, and when I'm accessing them from methods other than "Command" methods, i.e. Dialog Boxes, Palettes, etc.  This pattern has never given me any problems.

I would second the ReSharper thing.  After using it for the last three years, not only has it done a great job of refactoring and cleaning up code but it also has taught me to be a better coder along the way.
Revit 2019, AMEP 2019 64bit Win 10

BillZndl

  • Guest
Re: Transaction within a loop.
« Reply #19 on: September 25, 2014, 12:38:22 PM »
Thanks MC!

Understood and I think we're all good on this end.

FWIW: I just got a new project assigned to me today.
Convert an old AutoLisp 3d boat parameter calculater containing a nice GUI, that I made years ago,  over to .net!  8-)





nekitip

  • Guest
Re: Transaction within a loop.
« Reply #20 on: September 25, 2014, 03:32:43 PM »
Code: [Select]
The only reason I tried to run something on another thread,
was to keep the UI from "appearing to lock up" while a file search was going on.
Don't know if I accomplished running on a different thread
but by using the methods I found HERE:

I have not read carefully that code on that page, so I might be wrong, and if so, I might be missing a lot, so if anyone thinks I'm wrong, please correct me!!!
I claim that you can do whatever you want from .NET on any CPU core and thread you have, without any real worry or care, on yours app that is running in autocad BUT as long it is not dealing with autocad.
So, you can start three cpu intensive algorithms in paralell, search a lot on disk, open web page on usercontrol, and once in a while (when thread exits) set autocad editor to write a message: "it's ok" and the user or autocad will never know you have done anything wrong.
BUT, you cannot do even a simple task like open database and peek inside while you have other thread doing the same since only ONE, main thread, the one that was the first one when your app started can poke DB (or open some window or stuff).