相关疑难解决方法(0)

静态构造函数有什么用?

请向我解释一下静态构造函数的用法.我们为什么以及何时创建静态构造函数,是否可以重载一个?

c# constructor static-constructor

290
推荐指数
6
解决办法
16万
查看次数

C#线程安全与get/set

这是C#的详细问题.

假设我有一个带有对象的类,并且该对象受到锁的保护:

Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
    get {
         return property;
    }
    set { 
         property = value; 
    }
}
Run Code Online (Sandbox Code Playgroud)

我想要一个轮询线程来查询该属性.我还希望线程偶尔更新该对象的属性,有时用户可以更新该属性,并且用户希望能够看到该属性.

以下代码是否会正确锁定数据?

Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
    get {
         lock (mLock){
             return property;
         }
    }
    set { 
         lock (mLock){
              property = value; 
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

通过'正确',我的意思是,如果我想打电话

MyProperty.Field1 = 2;
Run Code Online (Sandbox Code Playgroud)

或者其他什么,我会在更新时锁定该字段?设置是由'get'函数范围内的equals运算符完成的,还是'get'函数(因此锁定)首先完成,然后设置,然后'set'被调用,从而绕过锁?

编辑:由于这显然不会做的伎俩,会是什么?我是否需要做以下事情:

Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
    get {
         MyObject tmp = null;
         lock …
Run Code Online (Sandbox Code Playgroud)

c# locking properties thread-safety

50
推荐指数
3
解决办法
8万
查看次数

参考分配线程安全吗?

我正在C#中构建一个多线程缓存,它将包含一个Car对象列表:

public static IList<Car> Cars {get; private set;}
Run Code Online (Sandbox Code Playgroud)

我想知道在没有锁定的情况下更改线程中的引用是否安全?

例如

private static void Loop()
{
  while (true)
  {
    Cars = GetFreshListFromServer();
    Thread.Sleep(SomeInterval);
  }
}
Run Code Online (Sandbox Code Playgroud)

基本上,它归结为是否为汽车分配新的参考是原子的还是不是我想的.

如果不是,我显然必须为我的汽车使用私人领域,并锁定获取和设置.

c# thread-safety

36
推荐指数
1
解决办法
1万
查看次数

单例模式如何在Web上下文中工作?

因此,使用单例模式的对象只能有一个实例.这在网站上如何运作?

问题:

  1. 单身对象是否对网站的每个客户/访客都是唯一的?即单个对象是否获得一个PER客户端实例?
  2. Web应用程序中的对象只持续几秒钟,因此如果两个客户端同时访问网站,则两个客户端都将尝试创建单个对象.这是否意味着有人会看到一个例外,游客会看到这个例外情况?我试过谷歌搜索,但找不到直接的答案.我只想找一点澄清.

c# asp.net singleton design-patterns

19
推荐指数
1
解决办法
1万
查看次数

静态变量的线程安全初始化

我一直在使用这种模式来初始化我的类中的静态数据.它看起来对我来说是安全的,但我知道细微的线程问题是多么微妙.这是代码:

public class MyClass // bad code, do not use
{
    static string _myResource = "";
    static volatile bool _init = false;
    public MyClass()
    {
        if (_init == true) return;
        lock (_myResource)
        {
            if (_init == true) return;
            Thread.Sleep(3000); // some operation that takes a long time 
            _myResource = "Hello World";
            _init = true;
        }
    }
    public string MyResource { get { return _myResource; } }
}
Run Code Online (Sandbox Code Playgroud)

这里有洞吗?也许有一种更简单的方法可以做到这一点.

更新:共识似乎是静态构造函数是要走的路.我使用静态构造函数提出了以下版本.

public class MyClass
{
    static MyClass() // a static constructor
    { …
Run Code Online (Sandbox Code Playgroud)

c# singleton multithreading

15
推荐指数
2
解决办法
8723
查看次数

为什么(或不是)在构造函数中设置字段是否安全?

假设你有一个像这样的简单类:

class MyClass
{
    private readonly int a;
    private int b;

    public MyClass(int a, int b) { this.a = a; this.b = b; }

    public int A { get { return a; } }
    public int B { get { return b; } }
}
Run Code Online (Sandbox Code Playgroud)

我可以以多线程方式使用这个类:

MyClass value = null;
Task.Run(() => {
    while (true) { value = new MyClass(1, 1); Thread.Sleep(10); }
});
while (true)
{
    MyClass result = value;
    if (result != null && (result.A != 1 || …
Run Code Online (Sandbox Code Playgroud)

c# multithreading volatile memory-model

13
推荐指数
1
解决办法
951
查看次数

如果静态只读成员调用静态方法来获取值,它是否同步完成?

鉴于:

public class MyClass
{
    private static readonly Dictionary<string,int> mydict = CreateDictionary();

    private static Dictionary<string,int> CreateDictionary() { ... }
}
Run Code Online (Sandbox Code Playgroud)

这是同步完成的吗?(即可以两次快速实例化MyClass原因CreateDictionary()被调用两次?

c# static synchronous

11
推荐指数
2
解决办法
610
查看次数

创建单个ChannelFactory <T>并重用客户端连接

在我们的SharePoint/ASP.NET环境中,我们有一系列数据检索器类,这些类都来自通用接口.我被分配了创建数据检索器的任务,该数据检索器可以使用WCF与其他SharePoint场远程通信.我现在实现它的方式ChannelFactory<T>是在静态构造函数中创建单例,然后由远程数据检索器的每个实例重用,以创建单独的代理实例.我认为这样可以很好地工作,因为那时ChannelFactory只在app域中实例化一次并且它的创建保证是线程安全的.我的代码看起来像这样:

public class RemoteDataRetriever : IDataRetriever
{
    protected static readonly ChannelFactory<IRemoteDataProvider>
        RequestChannelFactory;

    protected IRemoteDataProvider _channel;

    static RemoteDataRetriever()
    {
        WSHttpBinding binding = new WSHttpBinding(
            SecurityMode.TransportWithMessageCredential, true);

        binding.Security.Transport.ClientCredentialType =
            HttpClientCredentialType.None;

        binding.Security.Message.ClientCredentialType =
            MessageCredentialType.Windows;

        RequestChannelFactory = 
            new ChannelFactory<IRemoteDataProvider>(binding);
    }

    public RemoteDataRetriever(string endpointAddress)
    {
        _channel = RemoteDataRetriever.RequestChannelFactory.
            CreateChannel(new EndpointAddress(endpointAddress));
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,这是一个很好的设计吗?我想,一旦ChannelFactory创建,我不需要担心线程安全,因为我只是用它来打电话,CreateChannel()但我错了吗?它是在改变状态还是在幕后做一些可能导致线程问题的时髦的东西?另外,我是否需要在某个地方放置一些代码(静态终结器?)来手动处理ChannelFactory或者我可以假设每当IIS重新启动它时,它会为我做所有的清理工作吗?

相关:ChannelFactory重用策略

wcf singleton static-constructor thread-safety channelfactory

10
推荐指数
1
解决办法
1万
查看次数

静态初始化保证单线程安全吗?(C#)

可能重复:
C#静态构造函数线程是否安全?

Jon Skeet在http://csharpindepth.com/Articles/General/Singleton.aspx上的精彩文章以及我读过的其他文章清楚地表明,双重检查锁定在C#和Java中都不起作用,除非有明确标记实例为"易变".如果不这样做,则将其与null进行比较的检查可能会返回false,即使实例构造函数尚未完成运行.在Skeet先生的第三个样本中,他清楚地说明了这一点:"Java内存模型不能确保构造函数在将新对象的引用分配给实例之前完成.Java内存模型经历了1.5版的重新修改,但是在没有volatile变量的情况下,-check锁定仍然被破坏(如在C#中)

但是,大多数人都同意(包括Skeet先生,他的文章中的第4和第5个样本),使用静态初始化是获取线程安全单例实例的简单方法.他声称"C#中的静态构造函数被指定仅在创建类的实例或引用静态成员时执行,并且每个AppDomain只执行一次."

这是有道理的,但似乎缺少的是保证仅在构造函数完成后才分配对新对象的引用 - 否则我们会遇到使得双重检查锁定失败的同类问题,除非您标记实例像挥发性的.是否有保证,当使用静态初始化来调用实例构造函数(而不是从属性的get {}调用实例构造函数时,就像我们使用双重检查锁定一样),构造函数将在任何其他线程之前完全完成可以获得对象的引用?

谢谢!

c# singleton multithreading constructor

7
推荐指数
2
解决办法
6924
查看次数

C# - 静态只读字符串 - 可能遇到多线程问题?

public class MyClass<T>
{
    public static readonly String MyStringValue;

    static MyClass()
    {
        MyStringValue = GenerateString();
    }

    private static String GenerateString()
    {
        //Dynamically generated ONCE per type (hence, not const)
    }

    public void Foo()
    {
        Console.WriteLine(MyStringValue);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的理解是,在类上调用静态构造函数之前,不会生成静态readonly String.但是,在访问其中一个静态方法或变量之前,不会调用静态构造函数.

在多线程环境中,是否可能因此而遇到问题?基本上,静态构造函数是默认单例锁定还是我自己必须这样做?那是......我必须做以下事情:

private static Object MyLock;

static MyClass()
{
    lock(MyLock)
    {
        if (MyStringValue == null)
            MyStringValue = GenerateString();
    }
}
Run Code Online (Sandbox Code Playgroud)

c# singleton static multithreading readonly

5
推荐指数
1
解决办法
738
查看次数

这些单实例实现是否同样是线程安全的?

我相信第一个代码示例是一个简单的Singleton实现,我不确定它是否是线程安全的.作为类,EventSourceLogger派生自EventSource,它不是静态的,这个类本身不能只是一个静态类(这本来更方便 - 尽管在单一和静态之间进行权衡).

为了简洁起见,我从一个更彻底的特定已知线程安全实现恢复到此实现 - 在同事代码中喜欢这种方法的外观之后.我丢了什么?

目前的实施

[EventSource(Name = "EventSourceLogger")]
public class EventSourceLogger : EventSource
{
    public static readonly EventSourceLogger Logger = new EventSourceLogger();`
}
Run Code Online (Sandbox Code Playgroud)

以前的实施

[EventSource(Name = "EventSourceLogger")]
public class EventSourceLogger : EventSource
{
    private static EventSourceLogger instance;

    private EventSourceLogger()
    {
    }

    public static EventSourceLogger Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new EventSourceLogger();
             }

            return instance;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

c# singleton static

5
推荐指数
0
解决办法
55
查看次数

静态类继承自抽象类?

所以我有一个类A。它定义了很多行为(方法),但也留下了很多子类来实现。这个类永远不会有实例。这只是定义所有子类共有的行为。将扩展 A 的子类(A1、A2、A3 等)都将是单例。我不希望这些子类有多个实例。

因此,最明显的方法是创建一个抽象类 A,然后创建扩展 A 的静态类 A1、A2、A3。

但显然,这在 C# 中是不允许的。我认为这是有充分理由的。微软的人可能比我更了解面向对象的软件设计。但我只需要一些帮助来弄清楚为什么这个设计“很差”,以及什么是替代的更好的设计。


我正在使用 WCF 编写 RESTful API。该服务将在一堆数据库表上执行 CRUD 操作。有很多代码对于所有表来说都是通用的,并且很多代码对于每个表来说都是特定的。此外,在任何给定时间只能对表执行一项操作。

所以我想我可以有一个抽象类TableHandler。然后是它的多个扩展,例如等TableAHandlerTableBHandler由于我只想要这些子类的一个实例,所以我想将它们设为静态。

c# oop inheritance abstract-class static-classes

2
推荐指数
1
解决办法
4057
查看次数

单身模式混乱

按照单身模式,

public sealed class Singleton
{
    static Singleton instance=null;

    Singleton()
    {
    }

    public void abc(){
    }

    public static Singleton Instance
    {
        get
        {
            if (instance==null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

以上不是线程安全的.两个不同的线程都可以评估测试if(instance == null)并发现它是真的,然后两个都创建实例,这违反了单例模式.

混淆是实例是静态的,一旦在UI线程或其他线程上调用它,它是如何为null的?

编辑

我打算说,一旦我调用了Singleton.Instance.abc(); Singleton.Instance在手动处理之前不应为null.对?

c#

1
推荐指数
1
解决办法
277
查看次数