C# StringBuilder线程安全

C# StringBuilder线程安全,c#,ado.net,thread-safety,stringbuilder,C#,Ado.net,Thread Safety,Stringbuilder,我已经为SqlCommand编写了一个扩展方法来执行一批命令,我称之为ExecuteBatchNonQuery。这个很好用。我已更改为返回消息输出,为此,我必须创建一个从InfoMessage调用的方法。它附加到一个stringbuilder,我必须对其进行静态处理。我担心这个stringbuilder不是线程安全的。我必须使用一个静态的,有没有任何方法可以使它线程安全,或者有其他选择 internal static class SqlCommandHelper { private st

我已经为SqlCommand编写了一个扩展方法来执行一批命令,我称之为ExecuteBatchNonQuery。这个很好用。我已更改为返回消息输出,为此,我必须创建一个从InfoMessage调用的方法。它附加到一个stringbuilder,我必须对其进行静态处理。我担心这个stringbuilder不是线程安全的。我必须使用一个静态的,有没有任何方法可以使它线程安全,或者有其他选择

internal static class SqlCommandHelper
{
    private static readonly StringBuilder StringBuilder = new StringBuilder();

    internal static string ExecuteBatchNonQuery(this SqlCommand cmd, string sql)
    {
        SqlConnection conn = cmd.Connection;
        conn.Open();
        conn.InfoMessage += MyConnectionInfoMessage;
        string sqlBatch = string.Empty;
        sql += "\nGO"; // make sure last batch is executed.
        StringBuilder.Clear();
        try
        {
            foreach (string line in sql.Split(new string[2] { "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries))
            {
                if (line.ToUpperInvariant().Trim() == "GO")
                {
                    cmd.CommandText = sqlBatch;
                    cmd.ExecuteNonQuery();
                    sqlBatch = string.Empty;
                }
                else
                {
                    sqlBatch += line + "\n";
                }
            }
        }
        finally
        {
            conn.Close();
        }
        return StringBuilder.ToString();
    }

    private static void MyConnectionInfoMessage(object sender, SqlInfoMessageEventArgs e)
    {
        StringBuilder.AppendLine(e.Message);
    }
}

StringBuilder应该是一个局部变量。可以使用Lambda表达式来实现这一点:

internal static class SqlCommandHelper
{
    internal static string ExecuteBatchNonQuery(this SqlCommand cmd, string sql)
    {
        var sb = new StringBuilder(); 
        SqlConnection conn = cmd.Connection;
        conn.Open();
        conn.InfoMessage += (sender, e) => { sb.AppendLine(e.Message); };
        string sqlBatch = string.Empty;
        sql += "\nGO"; // make sure last batch is executed.
        sb.Clear();
        try
        {
            foreach (string line in sql.Split(new string[2] { "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries))
            {
                if (line.ToUpperInvariant().Trim() == "GO")
                {
                    cmd.CommandText = sqlBatch;
                    cmd.ExecuteNonQuery();
                    sqlBatch = string.Empty;
                }
                else
                {
                    sqlBatch += line + "\n";
                }
            }
        }
        finally
        {
            conn.Close();
        }
        return sb.ToString();
    }
}

StringBuilder应该是一个局部变量。可以使用Lambda表达式来实现这一点:

internal static class SqlCommandHelper
{
    internal static string ExecuteBatchNonQuery(this SqlCommand cmd, string sql)
    {
        var sb = new StringBuilder(); 
        SqlConnection conn = cmd.Connection;
        conn.Open();
        conn.InfoMessage += (sender, e) => { sb.AppendLine(e.Message); };
        string sqlBatch = string.Empty;
        sql += "\nGO"; // make sure last batch is executed.
        sb.Clear();
        try
        {
            foreach (string line in sql.Split(new string[2] { "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries))
            {
                if (line.ToUpperInvariant().Trim() == "GO")
                {
                    cmd.CommandText = sqlBatch;
                    cmd.ExecuteNonQuery();
                    sqlBatch = string.Empty;
                }
                else
                {
                    sqlBatch += line + "\n";
                }
            }
        }
        finally
        {
            conn.Close();
        }
        return sb.ToString();
    }
}