I am using SMO to script out my objects from Sql server database using .Net code. But as of now I am going through a sequential loop.
foreach(var table in TableCollection)
{
var stringCollection=table.Script();
}
It is working fine. But when I convert the same loop to a Parallel.ForEach
loop like:
Parallel.ForEach(TableCollection,table=>
{
var stringCollection=table.Script();
});
It fails to script. Is there anybody who has used the same kind of approach or any other approach to script out objects from Sql server in parallel?
UPDATE :
I haven't been able to work out Parallel LOOP as of now but I have used below mentioned code :
server.SetDefaultInitFields(true);
It improves performance up-to some extent.
It seems SMO wasn't built in a thread-safe manner. When you call Script()
on a Table
, it uses some shared state from its Server
, so you can't execute it on two tables from the same Server
. But you can work around that by creating new Server
object for each Table
:
private static TableCollection GetTables()
{
Server server = new Server(…);
Database database = server.Databases[…];
var tables = database.Tables;
return tables;
}
…
Parallel.For(0, GetTables().Count,
i =>
{
var stringCollection = GetTables()[i].Script();
…
});
This will make your queries parallel, but I have no idea whether it will make them actually faster.
EDIT: If you want to create one Server
for each thread, you could use an overload of Parallel.For()
that allows thread-local initialization. Something like:
Parallel.For(0, GetTables().Count,
() => GetTables(),
(i, _, tables) =>
{
var stringCollection = tables[i].Script();
…
return tables;
},
tables => { });
This way, each thread will have its own Server
object, but only one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With