Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 同一过程的多个SQL/CLR调用是否同时运行(如线程)?_C#_Sql Server_Clr_Sqlclr - Fatal编程技术网

C# 同一过程的多个SQL/CLR调用是否同时运行(如线程)?

C# 同一过程的多个SQL/CLR调用是否同时运行(如线程)?,c#,sql-server,clr,sqlclr,C#,Sql Server,Clr,Sqlclr,我有一个单例(因为我认为始终提供这些设置是有用的)来表示一些设置,这些设置将在clr过程调用开始时清除旧设置并从数据库加载新设置 但是如果CLR调用像线程一样处理,我可能会在某个时刻遇到问题,即设置在我想要访问它们的时候被清除 那么这会是一个问题吗?我可以用一个简单的对象锁来解决这个问题吗 编辑: 代码示例设置: public class Settings { public static Settings Default { get { return _defau

我有一个单例(因为我认为始终提供这些设置是有用的)来表示一些设置,这些设置将在clr过程调用开始时清除旧设置并从数据库加载新设置

但是如果CLR调用像线程一样处理,我可能会在某个时刻遇到问题,即设置在我想要访问它们的时候被清除

那么这会是一个问题吗?我可以用一个简单的对象锁来解决这个问题吗

编辑:

代码示例设置:

public class Settings
{
    public static Settings Default
    {
        get { return _default ?? (_default = new Settings()); }
    }
    private static Settings _default;

    private Dictionary<string, string> _settingsDict;

    private Settings()
    {
        _settingsDict = new Dictionary<string, string>();
    }

    public void ReloadSettings()
    {
        _settingsDict.Clear();

        using (var connection = new SqlConnection("context connetion=true"))
        using (var command = connection.CreateCommand())
        {
            command.CommandText = ...
            connection.Open();

            // Read Settings with DataReader into _settingsDict
        }
    }

    public string Get(string key) {
        get { return _settingsDict["key"] }
    }
}

只需以事务方式重新加载并使用ConcurrentDictionary即可

起点:

SQL-CLR中的线程与普通windows代码有很大不同,因为它由一种称为“SQLOS”的东西来处理。线程被分配给给定任务的调度程序,并且它们不能重新分配到其他线程,因此您可以在其中作出一些假设。也就是说

不幸的是,并发字典使用了锁定,因此您必须非常小心,因为它需要“不安全”的权限集

Adam Mechanical在这方面做了很好的介绍:


当你运行一个进程时,它几乎是作为自己的线程旋转出来的。因此,两个人打电话会发生冲突

最简单的方法是不改变现有的字典,而是创建一个新的字典,并以原子方式将其写入全局变量

为了拥有非只读静态变量,您需要SQL Server中的不安全权限。请注意这一点。您可以通过使用包装器类来避免此要求

class MutableCell<T> { public volatile T value; }
static readonly MutableCell<...> myVar = new ...();
类可变单元格{public volatile T value;}
静态只读可变单元格myVar=new…();
我添加了
volatile
,这在这里是必需的,因为多个线程正在竞相读取和写入该变量


一般来说,在SQLServer内部执行线程和可变状态并不是最好的主意。最好避免。你有风险引入非常困难和灾难性的bug。不过,您的场景看起来是合法的。

您能展示一下您的代码吗?如果您在问题中明确表示您是在专门讨论SQL/CLR,那将是一个好主意。这个问题目前只隐藏在标记中。我用一个代码示例和一个更好的标题更新了这个问题。仅仅使用线程安全的dict并不能使所有操作都是线程安全的。他仍然可以从不同的线程中看到一个空的dict。
class MutableCell<T> { public volatile T value; }
static readonly MutableCell<...> myVar = new ...();