You cannot call Clone from multiple threads, because the SqlCommand class itself is not a thread safe class. you must lock before cloning.
However, you can look at the SqlCommand.Clone() method using programs like Reflector , here is the actual code:
public SqlCommand Clone() { SqlCommand command = new SqlCommand(this); Bid.Trace("<sc.SqlCommand.Clone|API> %d#, clone=%d#\n", this.ObjectID, command.ObjectID); return command; } internal static void Trace(string fmtPrintfW, int a1, int a2) { if (((modFlags & ApiGroup.Trace) != ApiGroup.Off) && (modID != NoData)) { NativeMethods.Trace(modID, UIntPtr.Zero, UIntPtr.Zero, fmtPrintfW, a1, a2); } } [DllImport("System.Data.dll", EntryPoint="DllBidTraceCW", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Unicode)] internal static extern void Trace(IntPtr hID, UIntPtr src, UIntPtr info, string fmtPrintfW, int a1, int a2); private SqlCommand(SqlCommand from) : this() { this.CommandText = from.CommandText; this.CommandTimeout = from.CommandTimeout; this.CommandType = from.CommandType; this.Connection = from.Connection; this.DesignTimeVisible = from.DesignTimeVisible; this.Transaction = from.Transaction; this.UpdatedRowSource = from.UpdatedRowSource; SqlParameterCollection parameters = this.Parameters; foreach (object obj2 in from.Parameters) { parameters.Add((obj2 is ICloneable) ? (obj2 as ICloneable).Clone() : obj2); } }
You can see that it creates a new instance and adds all the properties of the old one to it, but it does not copy all the properties of β Connection , for example,β which means it is a shallow copy.
source share