Comments (21)
try to dispose the transaction manually rather than relying on the "using" statement.
from revit.async.
Or you can create a transaction in every loop
from revit.async.
On the second pass through the loop I get this exception :
await RevitTask.RunAsync(
async app =>
{
try
{
var document = app.ActiveUIDocument.Document;
int count = 20;
for (int i = 0; i < count; i++)
{
string family_2d = "Family";
string symbol_2d = "Symbol";
using (Transaction transaction = new Transaction(document))
{
transaction.Start("Insert");
var symbol = document.FindSymbol(family_2d, symbol_2d);
FamilyInstance instance = document.Create.NewFamilyInstance(new XYZ(0, 0, 0), symbol, StructuralType.NonStructural);
await Task.Delay(1000);
transaction.Commit();
}
Informations = $"Insert {i + 1}/{count}";
}
Informations = "Finished";
}
catch (Exception ex)
{ }
});
from revit.async.
How about delaying after the transaction has been committed?
from revit.async.
I tried too but it causes the same exception, for your information it happens on this line: " transaction.Start("Insert");"
from revit.async.
What is the exception?
from revit.async.
The 1st transaction is commited but the next one does not work.
The exception is: "Starting a transaction from an external application running outside of API context is not allowed." and this happens at the line: " transaction.Start("Insert");"
await RevitTask.RunAsync(
async app =>
{
try
{
var document = app.ActiveUIDocument.Document;
int count = 20;
for (int i = 0; i < count; i++)
{
string family_2d = "Family";
string symbol_2d = "Symbol";
using (Transaction transaction = new Transaction(document))
{
transaction.Start("Insert");
var symbol = document.FindSymbol(family_2d, symbol_2d);
FamilyInstance instance = document.Create.NewFamilyInstance(new XYZ(0, 0, 0), symbol, StructuralType.NonStructural);
transaction.Commit();
}
await Task.Delay(1000);
Informations = $"Insert {i + 1}/{count}";
}
Informations = "Finished";
}
catch (Exception ex)
{ }
});
from revit.async.
Exactly. The Task.Delay() results in the rest code to be running in a worker thread. You can try to use RevitTask.RunAsync in the loop to execute Revit API
from revit.async.
It works by doing this:
try
{
int count = 20;
for (int i = 0; i < count; i++)
{
string family_2d = "Family";
string symbol_2d = "Symbol";
await RevitTask.RunAsync(
app =>
{
Informations = $"Insert {i + 1}/{count}";
var document = app.ActiveUIDocument.Document;
using (Transaction transaction = new Transaction(document))
{
transaction.Start("Insert");
var symbol = document.FindSymbol(family_2d, symbol_2d);
FamilyInstance instance = document.Create.NewFamilyInstance(new XYZ(0, 0, 0), symbol, StructuralType.NonStructural);
transaction.Commit();
}
});
await Task.Delay(1000);
}
Informations = "Finished";
}
catch (Exception ex)
{
}
I was thinking of creating a single transaction for the loop how can I do that? Will creating multiple transactions impact processing time?
Another question: If I want to update the "Information" property of my viewmodel, in RevitTask.RunAsync, I have to use the Dispatcher of my interface and do this:
public void UpdateInformations(string message)
{
_dispatcher.Invoke(() =>
{
Informations = message;
}, DispatcherPriority.Background);
}
from revit.async.
As far as I know, you can update viewmodel properties without caring about which thread your code is currently running. The viewmodel fires the "PropertyChanged" event to notify the UI to update in proper time.
from revit.async.
try
{
RevitTask.RunAsync(async (app) =>
{
int count = 20;
var document = app.ActiveUIDocument.Document;
Transaction transaction = new Transaction(document);
transaction.Start("Insert");
var symbol = document.FindSymbol(family_2d, symbol_2d);
for (int i = 0; i < count; i++)
{
string family_2d = "Family";
string symbol_2d = "Symbol";
await RevitTask.RunAsync(
app =>
{
Informations = $"Insert {i + 1}/{count}";
FamilyInstance instance = document.Create.NewFamilyInstance(new XYZ(0, 0, 0), symbol, StructuralType.NonStructural);
});
await Task.Delay(1000);
}
transaction.Commit();
transaction.Dispose();
Informations = "Finished";
});
}
catch (Exception ex)
{
}
How about this?
from revit.async.
I get this exception: "System.Runtime.InteropServices.SEHException : 'Un composant externe a levé une exception.'"
from revit.async.
How did you implement your viewmodel? Especially in the "Information" property
from revit.async.
With your example I get this exception at this line:
FamilyInstance instance = document.Create.NewFamilyInstance(new XYZ(0, 0, 0), symbol, StructuralType.NonStructural);
from revit.async.
try
{
RevitTask.RunAsync(async (app) =>
{
int count = 20;
var document = app.ActiveUIDocument.Document;
Transaction transaction = new Transaction(document);
transaction.Start("Insert");
for (int i = 0; i < count; i++)
{
string family_2d = "Family";
string symbol_2d = "Symbol";
await RevitTask.RunAsync(
app =>
{
Informations = $"Insert {i + 1}/{count}";
var document = app.ActiveUIDocument.Document;
var symbol = document.FindSymbol(family_2d, symbol_2d);
FamilyInstance instance = document.Create.NewFamilyInstance(new XYZ(0, 0, 0), symbol, StructuralType.NonStructural);
});
await Task.Delay(1000);
}
transaction.Commit();
transaction.Dispose();
Informations = "Finished";
});
}
catch (Exception ex)
{
}
Sorry, I don't have access to Revit at the moment. Please try entering the code again.
from revit.async.
It doesn't change anything, same exception
try
{
RevitTask.RunAsync(async (app) =>
{
int count = 20;
var document = app.ActiveUIDocument.Document;
Transaction transaction = new Transaction(document);
transaction.Start("Insert");
for (int i = 0; i < count; i++)
{
string family_2d = "Family";
string symbol_2d = "Symbol";
await RevitTask.RunAsync(
app2 =>
{
Informations = $"Insert {i + 1}/{count}";
var document2 = app2.ActiveUIDocument.Document;
var symbol = document2.FindSymbol(family_2d, symbol_2d);
FamilyInstance instance = document2.Create.NewFamilyInstance(new XYZ(0, 0, 0), symbol, StructuralType.NonStructural);
});
await Task.Delay(1000);
}
transaction.Commit();
transaction.Dispose();
Informations = "Finished";
});
}
catch (Exception ex)
{
}
from revit.async.
I haven't used Revit in years. It seems that the beginning and committing of a transaction cannot be separated in different Revit contexts.
from revit.async.
After this is only a part of code in fact I encounter another problem, when I execute my command my Information property is not updated in my interface, I only see the last message of the loop
from revit.async.
try
{
int count = 20;
for (int i = 0; i < count; i++)
{
string family_2d = "Family";
string symbol_2d = "Symbol";
// update information right before you enter an external event handler
Informations = $"Insert {i + 1}/{count}";
await RevitTask.RunAsync(
app =>
{
var document = app.ActiveUIDocument.Document;
using (Transaction transaction = new Transaction(document))
{
transaction.Start("Insert");
var symbol = document.FindSymbol(family_2d, symbol_2d);
FamilyInstance instance = document.Create.NewFamilyInstance(new XYZ(0, 0, 0), symbol, StructuralType.NonStructural);
transaction.Commit();
}
});
await Task.Delay(1000);
}
Informations = "Finished";
}
catch (Exception ex)
{
}
Slight changes to the working code.
from revit.async.
Is the issue still ongoing?
from revit.async.
Yes but I close the issue
from revit.async.
Related Issues (13)
- NuGet HOT 1
- Hanging when calling via CefSharp HOT 6
- Can't schedule more than 1 task in a synchronous method HOT 4
- A strongly-named assembly is required HOT 2
- Is there a way to trigger the SaveFamilyCommand() with a MouseEventArgs ? HOT 2
- RevitTask.RunAsync freezes GUI HOT 9
- Execute Console App from Revit HOT 6
- IExternalApplication Implementation HOT 2
- RevitTask.RunAsync() returns before Revit HOT 7
- Sometimes InvalidOperationException: 'Starting a transaction from an external application..." HOT 2
- Getter for UIApplication HOT 6
- RevitTask.Initialize() Two Addin HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from revit.async.