.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Create DBTEXT element in BackgroundWorker vb .net?

16 REPLIES 16
SOLVED
Reply
Message 1 of 17
prmgame
1984 Views, 16 Replies

Create DBTEXT element in BackgroundWorker vb .net?

Even after much searching and asking for help, I have not come to a solution for creating DBTEXT elements within a BackgroundWorker, this element has problem with the alignment point. So there is an example ZIP to anyone who can help, just run the command and check the elements created, you will see that I'm creating the element with the point in alinahmento MIDLECENTER but the result is not correct.

I am creating other elements in the same way and they had no problems (MTEXT, POLYLINE, CIRCLE, SPLINE, LINE, etc. ..), they are correct, but the element and the element DBTEXT block that contains attributes present problems in the alignment points.

16 REPLIES 16
Message 2 of 17
Artvegas
in reply to: prmgame

I ran your code and see what you mean with the alignment not being right. I tried a few things but to avail. I'm curious why you want to multi-thread this. For each DBText item you are including the overhead of a worker thread as well as additional overhead for creating seperate transactions, for what seems a relatively small piece of work. If you were to create the DBText entities in a single transaction on the main thread, i can't imagine much difference in performance. And you would avoid dealing with these kind of issues, particularly as the Autodesk guys openly state that AutoCAD isn't geared for threading with the API's. Are you looking to implement more intensive per item code in the future? If you're just after a way to notify users of your progress you could do this from within your loop, options include AutoCAD's progress bar API component, or using a dispatch call for your custom progress bar (e.g. System.Windows.Forms.Application.DoEvents()).
Message 3 of 17
Artvegas
in reply to: Artvegas

Correction it is a single worker thread with multiple transactions.
Message 4 of 17
prmgame
in reply to: prmgame

OK I understand, I should create the elements in a single transaction block, perfect, but it does not change the fact that when creating the element within DBTEXT  a Background Worker and the alignment point set to MIDLECENTER results in the element with the point of hanging indent.  I am using Background Worker to perform this process because there is much information and without the Background Worker AutoCAD indicates NOTRESPONDING and we have no idea that while the process is.

 

 See this attachment to get an idea of the problem, and thank you.

Message 5 of 17
prmgame
in reply to: prmgame

I am using BackgroundWorker because we have thousands of elements to be created in the example represents the element DBTEXT a lot in a court in one state, I am reading data from an xml and caring for autocad, but this process is resulting in NOTRESPONDING, we know that yet the process is running, but we have no idea of ​​progress, so I decided to use BackgroundWorker that worked well until you create the element and DBTEXT BLOCK, gave error in alignment point. Thank you for help!

Message 6 of 17
Artvegas
in reply to: prmgame

One suggestion I have is to look into the DBText.AdjustAlignment() method. There's some information about this one in the ObjectARX docs.

 

I tried to call this within your NewDBText() function but it had no effect. However after running your tool, I iterated model space and called the DBText.AdjustAlignment() method on all of the created DBText entities and this corrected the alignments. Below is the command I used to do this in C#.

 

Is it possible for you to update the aligments seperately after your worker thread has finished adding DBText entities?

 

 

[CommandMethod("DBTextUpdateAlignments")]
public static void DBTextUpdateAlignments()
{
	Document doc = AcApplication.DocumentManager.MdiActiveDocument;
	Database db = doc.Database;

	using (Transaction tr = db.TransactionManager.StartTransaction())
	{
		BlockTableRecord btr = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);

		foreach (ObjectId id in btr)
		{
			DBText text = tr.GetObject(id, OpenMode.ForRead) as DBText;
			if (text != null)
			{
				text.UpgradeOpen();
				text.AdjustAlignment(db);
			}
		}

		tr.Commit();
	}
}

 

 

Message 7 of 17
prmgame
in reply to: Artvegas

Thank you, I will apply this solution to the project, I am very grateful for the attention and time wasted! I'll soon be posting the results!

Message 8 of 17
prmgame
in reply to: prmgame

Greetings Artvegas,  I applied the solution you pointed out using the method (AdjustAlignment), it worked perfectly if executed after completion of the process BackgroundWorker.  Unfortunately the same method does not result if used within the process BackgroundWorker, but even being used after the process was fast and solved my problems, so I would like to thank for helping OK.

Message 9 of 17
Artvegas
in reply to: prmgame

Awesome! Yeah it only worked after completion for me too. Also I was just thinking that you could try to return an ObjectIdCollection from your background worker - i.e. instead of iterating block table records. But maybe you don't need to be that fast 🙂
Message 10 of 17
prmgame
in reply to: Artvegas

I understand, using the objects rendered in a ObjectIdCollection I could make adjustments more quickly this?

Message 11 of 17
Artvegas
in reply to: prmgame

Exactly. When your worker finishes you could return a collection of ObjectIds to the main thread. Then you wouldn't have to search for them, nor would you be unnecessarily opening and applying the DBText.AdjustAlignment() method to text entities that existed in the database before you ran the worker.

I'm not sure how much difference this will make. I'm thinking it would depend upon on how many other entities (particularly text entities) you have in your drawings. But this is what I would do.

For an example of how to return data from a background worker you can refer to the "Return a value from the background operation" at the bottom of this post :
http://www.c-sharpcorner.com/uploadfile/Ashush/using-the-backgroundworker-component/

Art

Message 12 of 17
prmgame
in reply to: Artvegas

I understand I did what you recommended and it worked perfectly, had a gain in performance and I am pleased with the results, and again thank Artvegas!

Message 13 of 17
artc2
in reply to: prmgame

I just wanted to re-iterate the warning that someone else already made that AcDb (the entity code) is absolutely not multi-thread safe.  So, while your background thread is running, if the Acad main thread does anything that uses any of the AcDb code that text is using, you are very likely to have problems.

Message 14 of 17
Artvegas
in reply to: artc2

What artc2 wrote couldn't be any clearer. I would try something like this: http://drive-cad-with-code.blogspot.com.au/2010/12/showing-progress-window-when-running.html
Message 15 of 17
prmgame
in reply to: artc2

I understand that the risk of performing transactions outside the main thread can cause problems, but I've imported some 368,000 objects between (Polylines, Text, Blocks etc. ..), and so far had no problems, saved the file its countless times and performed tests and everything is correct.  Yet another study it more secure way to do the job, and I am studying the proposal made in a video (taget Gopinath, member of the Autodesk Developer), which teaches how to work with multi-thread smoothly.

 

Parallel Programming in an AutoCAD® Application

http://au.autodesk.com/?nd=class&session_id=8975

 

Thank Staff.

Message 16 of 17
Artvegas
in reply to: prmgame

Hi prmgame,

 

I just came across a link for another class at Autodesk University...

 

Multithreading and Message Handling in Windows® Presentation Foundation (WPF) Applications:
http://au.autodesk.com/?nd=class&session_id=8964

 

And the class description...

"If your AutoCAD® plug-in spends a long time processing data, you know how frustrated your users can get when their user interface freezes or Windows shows that all too familiar "Program Not Responding" message. How do you prevent that? Depending on what you are doing, you have a choice between message handling and multithreading. This class will show you when to use each technique and how to handle them both from within your WPF user interface."

 

I haven't watched it yet but it seems that this discusses the exact issue you are trying to address - so hopefully will be most useful to you.

Message 17 of 17
prmgame
in reply to: Artvegas

Hello Artvegas, 

 Yes, I'm watching the videos Autodesk AU, no doubt I'll be doing tests with the examples shown.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost