简体   繁体   English

是.NET double.ToString线程安全吗?

[英]Is .NET double.ToString threadsafe?

I'm seeing an issue in a production ASP.NET application that involves the following code, which is used to render the geocoordinates of a particular object: 我在生产ASP.NET应用程序中看到一个涉及以下代码的问题,该代码用于呈现特定对象的地理坐标:

private double _longitude;
private double _latitude;

public string ToCsvString()
{
    return _latitude + "," + _longitude;
}

Thread.CurrentThread.CurrentCulture will be set to different values based on the incoming request. Thread.CurrentThread.CurrentCulture将根据传入请求设置为不同的值。 The behavior I'm seeing is that the result of this function will vary independent of the threadlocal culture. 我看到的行为是这个函数的结果将独立于threadlocal文化而变化。 At times the decimal points and commas are incorrect for the current culture. 有时小数点和逗号对于当前文化是不正确的。 More strangely, it seems that once set wrong, the wrong value persists. 更奇怪的是,似乎一旦出错,错误的价值仍然存在。

Does ToString on double cache values? 对双缓存值进行ToString吗?

It shouldn't cache the values, especially because of the culture issue you mentioned. 它不应该缓存值,特别是因为您提到的文化问题。 Two things come to mind: 我想到两件事:

  1. How/where do you set the culture? 您如何/在何处设置文化? Perhaps there is a bug there? 也许那里有一个bug?
  2. Are you sure it is THIS place that creates the bug? 你确定它是创建的bug 这个地方? Perhaps the culture is different than you think? 也许文化与你想的不同? Perhaps the results of this function are cached elsewhere in your code? 也许这个函数的结果缓存在代码的其他地方?

为什么不使用允许您手动指定特定于区域性的IFormatProvider的显式ToString方法?

For rendering geocoordinates, I suggest that you best define your own fixed formatting or culture rather than leaving it for the framework, default culture setting or culture info of the running thread. 为了渲染地理坐标,我建议您最好定义自己的固定格式或文化,而不是将其留给框架,默认文化设置或正在运行的线程的文化信息。

I would do it like this to format it to 4 decimal points: 我会像这样把它格式化为4个小数点:

return _latitude.ToString("0.0000") + "," + _longitude.ToString("0.0000");

or 要么

string.Format("{0:0.0000}, "{1:0.0000}", _latitude, _longitude);

Or if you want the decimal separator to be culture specific, 或者,如果您希望小数点分隔符是特定于文化的,

CultureInfo ci = System.Globalization.CultureInfo.GetCultureInfo("en-AU");
return _latitude.ToString("N4", ci) + "," + _longitude.ToString("N4", ci);

如果您始终希望Double.ToString返回一致的值而不管文化,请使用InvariantCulture:

someDouble.ToString(CultureInfo.InvariantCulture); 

Operations such as ToString on double or any other immutable object are by definition thread safe. 对于double或任何其他不可变对象的ToString等操作,根据定义是线程安全的。 Since you are guaranteed that the state of those object never change an operation will always yield the same result, that result might however be based on the environment it's executed in but it will always yield the same result in the same environment. 由于您可以保证这些对象的状态永远不会更改,因此操作将始终产生相同的结果,但该结果可能基于它在其中执行的环境,但它将始终在相同的环境中产生相同的结果。 Since there are no side effects on immutable types ToString cannot cache the result 由于对不可变类型没有副作用,ToString无法缓存结果

Any page in msdn will show you the fact that "Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe" msdn中的任何页面都会向您显示“此类型的任何公共静态(在Visual Basic中共享)成员都是线程安全的事实。任何实例成员都不保证是线程安全的”

for instance look at this one http://msdn.microsoft.com/en-us/library/system.delegate.aspx 比如看看这个http://msdn.microsoft.com/en-us/library/system.delegate.aspx

So, double.ToString() is not guaranteed to be thread safe since it is an instance methods. 因此,double.ToString()不保证是线程安全的,因为它是一个实例方法。

I would echo what Anon suggested and use IformatProvider 我会回应Anon所建议的并使用IformatProvider

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM