在静态方法中使用Singleton实例

时间:2019-02-20 08:54:10

标签: c# .net static thread-safety singleton

我在Web应用程序中使用静态方法进行了调用。此方法使用其他类的单例实例。这个单例实例基本上是一个发出一些api请求的HttpClient。

目前,我没有任何机制可以对此进行自动多用户测试。这种方法有什么后果吗?我知道,如果不在其中使用静态变量,则通常的静态方法是线程安全的。但是我不确定在单例情况下它的行为。

dialog.modalPresentationStyle = .popover
dialog.popoverPresentationController?.delegate = self
dialog.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
dialog.popoverPresentationController?.sourceView = view
dialog.popoverPresentationController?.sourceRect = view.frame

1 个答案:

答案 0 :(得分:1)

为了避免线程问题,您至少需要以线程安全的方式实现单例。乔恩·斯凯特(Jon Skeet)的article描述了如何以线程安全的方式创建单例实例的一些方法。另外,您应确保单例的方法可以处理并行请求,也可以使用lock来同步调用。

在静态方法中使用Singleton的问题也是面向对象的设计之一。拥有一个单例并在应用程序的许多地方使用它很方便,但它也有缺点:

  • 同一个开发人员乍一看看不到您的方法依赖单例实例。这是一个隐藏的依赖项。
  • 此外,如果您需要其他行为(例如,在测试中。

因此,我建议考虑是否真的需要单例,或者是否可以将其作为参数注入到需要的方法中:

public static async Task<string> GetData(API api, string id)
{
    HttpResponseMessage response = await 
    api.Instance.GetAsync(string.Format(requestURL, id));
    response.EnsureSuccessStatusCode();

    // return URI of the created resource.
    return await response.Content.ReadAsStringAsync();
}

您可以将方法更改为可以调用的扩展方法,例如:

var result = await API.Instance.GetData("123");

您只需要在签名中添加this

public static async Task<string> GetData(this API api, string id)
{
  // ...
}