TheSwamp
Code Red => .NET => Topic started by: mkweaver on May 12, 2007, 11:35:59 AM
-
In the code below the Visual Studio IDE (2005 express) flags this "trans.Dispose()" with: Error 1 Name 'trans' is not declared.
Why? And what is the solution?
Thanks,
Mike
Private Function CreateLayer(ByVal strLayerName As String) As ObjectId
Dim db As Database = HostApplicationServices.WorkingDatabase
Try
Dim Trans As Transaction = db.TransactionManager.StartTransaction()
Dim ltable As LayerTable = Trans.GetObject(db.LayerTableId, OpenMode.ForRead)
If ltable.Has(strLayerName) Then
Return ltable.Item(strLayerName)
End If
Dim layNew As LayerTableRecord = New LayerTableRecord()
layNew.Color = Color.FromColorIndex(ColorMethod.ByAci, 2)
Return layNew.ObjectId
Catch ex As System.Exception
MsgBox("Error in CreateLayer Command" + ex.Message)
Finally
[color=red]trans.Dispose()[/color]
End Try
End Function
-
You need to declare trans outside(before) the try scope
-
See the difference between both names, what is?
-
See the difference between both names, what is?
VB is not case sensitive right?
-
You need to declare trans outside(before) the try scope
Okay, an observation and a questions then:
I considered that, but didn't think it would be an issue since both the Trans initialization and Dispose occur inside the Try Block.
If I declare Trans outside the Try block don't I run the risk of an unhandled exception on it's initialization? Is the only way, then, to dim Trans outside the Try block and initialize it inside?
Regarding the case, I use camelCase when I declare my vars then use them in lower case. The IDE will change the case to match the declaration when I get the spelling correct. This helps identify spelling errors.
-
See the difference between both names, what is?
VB is not case sensitive right?
I don't do VB.NET but just by reading: Name 'trans' is not declared - but I will check here, just to make myself sure. :)
-
I am not sure the VB syntax but you could either nest inside another try catch block or look at using the "using" statement.
is in C# would be
using (ResultBuffer ci1 = new ResultBuffer())
{
ci1.Add(new TypedValue(0, "CIRCLE"));
ci1.Add(new TypedValue(8, "0"));
ci1.Add(new TypedValue(10, pt1));
ci1.Add(new TypedValue(40, 2.5));
Sds.entMake(ci1);
}
ci1 get disposed when the scope ends
-
See the difference between both names, what is?
VB is not case sensitive right?
I don't do VB.NET but just by reading: Name 'trans' is not declared - but I will check here, just to make myself sure. :)
Good point. VB is Greek vb to me :-o
-
See the difference between both names, what is?
VB is not case sensitive right?
I don't do VB.NET but just by reading: Name 'trans' is not declared - but I will check here, just to make myself sure. :)
Good point. VB is Greek vb to me :-o
Yes... (I do not like it... super mickey mouse.... go for C# instead....!!!!!!)
Miguel, try the below code.... it works I mean it gets compiled (and yes you are right the compiler will make the appropriate change of case (for trans to Trans) first time playing with VB.NET
Private Function CreateLayer(ByVal strLayerName As String) As ObjectId
Dim db As Database = HostApplicationServices.WorkingDatabase
Dim Trans As Transaction = db.TransactionManager.StartTransaction()
Try
Dim ltable As LayerTable = Trans.GetObject(db.LayerTableId, OpenMode.ForRead)
If ltable.Has(strLayerName) Then
Return ltable.Item(strLayerName)
End If
Dim layNew As LayerTableRecord = New LayerTableRecord()
layNew.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, 2)
Return layNew.ObjectId
Catch ex As System.Exception
MsgBox("Error in CreateLayer Command" + ex.Message)
Finally
Trans.Dispose()
End Try
End Function
-
so then
using db As Database = HostApplicationServices.WorkingDatabase
blah blah blah
End using
and get rid of the dispose call
-
If I declare Trans outside the Try block don't I run the risk of an unhandled exception on it's initialization? Is the only way, then, to dim Trans outside the Try block and initialize it inside?
Yes, you run the risk that StartTransaction() failed to return
a valid Transaction.
But if that ever did happen, it's so serious/critical an error,
that your code should/must fail at that point.
IMHO, the Using construct is a lot easier to understand
and use, and helps avoid needlessly complicated code.
-
Agree with Tony, but you could dim it outside try and set to null/nothing, then inside try set it to a valid transaction....
-
Agree with Tony, but you could dim it outside try and set to null/nothing, then inside try set it to a valid transaction....
Would that work? I mean is null IDisposable ?
-
C#
Transaction tr = null;
try {
tr = db.TransactionManager.StartTransaction();
// more mojo here
} finally {
tr.Dispose();
}
I imagine you could do the same thing with VB.
-
C#
Transaction tr = null;
try {
tr = db.TransactionManager.StartTransaction();
// more mojo here
} finally {
tr.Dispose();
}
I imagine you could do the same thing with VB.
Ah, now I understand
Thanks
-
As others have said, the "Using" statement is basically a "short-cut" for this exact situation. It's used A LOT in .NET programming, so you will be seeing it constantly in code written by others. And since it's simpler, you will probably want to get familiar with it.
Both of the following snippets are equivalent:
Transaction tr = null;
try {
tr = db.TransactionManager.StartTransaction();
// more mojo here
} finally {
tr.Dispose();
}
using (Transaction tr = db.TransactionManager.StartTransaction();
{
// more mojo here
}
-
Transaction tr = null;
try {
tr = db.TransactionManager.StartTransaction();
// more mojo here
} finally {
tr.Dispose();
}
using (Transaction tr = db.TransactionManager.StartTransaction();
{
// more mojo here
}
Okay, using sure gives cleaner code, but is there any way to capture an error thrown when the initialization of TR fails?
-
I wouldn't initialize the 'tr' variable inside the try block, because
that would cause the code in the finally block to call Dispose()
on it, no matter what. That's not exactly what you want.
As far as equating try/finally to what using() does, this would
be closer:
Transaction tr = myDb.TransactionManager.StartTransaction()
try
{
// use 'tr' here
}
finally
{
if( tr != null )
tr.Dispose();
}
If you want to test to see if the tr variable was correctly
initialized, you do something like this:
Transaction tr = myDb.TransactionManager.StartTransaction()
if( tr == null )
throw new InvalidOperationException("No transaction!");
try
{
// use 'tr' here
}
finally
{
if( tr != null )
tr.Dispose();
}
The odds that StartTransaction() will fail to return a valid
Transaction is slim-to-none, but if it ever did happen, your
code should not attempt to deal with it, because it means
something is wrong at the API level, rather than in your
own code.
Transaction tr = null;
try {
tr = db.TransactionManager.StartTransaction();
// more mojo here
} finally {
tr.Dispose();
}
using (Transaction tr = db.TransactionManager.StartTransaction();
{
// more mojo here
}
Okay, using sure gives cleaner code, but is there any way to capture an error thrown when the initialization of TR fails?
-
Okay, it sounds like "using" is the way to go, then.
Thanks for the input everyone.
Mike Weaver
AlasCAD
-
Mkweaver
The using statement is not a replacement for try ...catch…finally. its purpose is to emit a dispose call on an object that that implements IDisposable. If you feel that a statement could potentially throw an exception, by all means wrap it with a try catch. Having said that, there is nothing wrong with having nested try…catch…finally blocks. Or sticking a “using” block inside of a try…catch. have fun 8-)
Dan