我们有一个.net 3.5多线程窗体表单应用程序。是启动4-5个后台工作人员/异步调用来检索数据。大约十分之一,其中一个线程抛出以下错误。有时错误是一个null异常,而是相同的调用堆栈。我们已经将该问题跟踪到该线程以某种方式失去了CultureInfo。还有其他人遇到过吗?
System.Threading.SynchronizationLockException: Object synchronization method was called from an unsynchronized block of code.
at System.Globalization.CultureTableRecord.GetCultureTableRecord(String name, Boolean useUserOverride)
at System.Globalization.CultureTableRecord.GetCultureTableRecord(Int32 cultureId, Boolean useUserOverride)
at System.Globalization.CultureInfo..ctor(Int32 culture, Boolean useUserOverride)
at System.Globalization.CultureInfo.GetCultureByLCIDOrName(Int32 preferLCID, String fallbackToString)
at System.Globalization.CultureInfo.InitUserDefaultUICulture()
at System.Globalization.CultureInfo.get_UserDefaultUICulture()
at System.Threading.Thread.get_CurrentUICulture()
at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)
at System.Environment.ResourceHelper.GetResourceStringCode(Object userDataIn)
at System.Environment.GetResourceFromDefault(String key)
at System.Diagnostics.StackTrace.ToString(TraceFormat traceFormat)
at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
at System.IO.StreamWriter.Init(Stream stream, Encoding encoding, Int32 bufferSize)
at System.IO.StreamWriter..ctor(Stream stream, Encoding encoding, Int32 bufferSize)
at System.Web.Services.Protocols.SoapHttpClientProtocol.GetWriterForMessage(SoapClientMessage message, Int32 bufferSize)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Serialize(SoapClientMessage message)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
答案 0 :(得分:1)
尝试使用CultureInfo.DefaultThreadCurrentCulture
和/或CultureInfo.DefaultThreadCurrentUICulture
播放整个域的默认文化,看看是否有帮助。总而言之,您将能够确保它是否与线程的文化相关
UPD :在值类型上使用lock
,Monitor
等同步方法时,可能会抛出该特定异常,调用同步方法将设置值,每次创建新值。我怀疑它可能是框架中的这种严重错误。
您可以查看同步代码吗?
UPD2 :好的,让我们尝试 调试 。
接下来,启用可帮助您的.NET Framework debugging 找到错误
之后,很有可能为您解决问题的解决方法/解决方案
答案 1 :(得分:1)
从查看调用堆栈,这似乎是一个框架错误(各种各样)。似乎StreamWriter构造函数通过一系列复杂的调用执行非线程安全操作(访问GetCultureTableRecord)。我的建议是将你的调用序列化为StreamWriter构造函数:
// Put this somewhere convenient
public static Object swConstructorLock = new Object();
然后,当您创建StreamWriters时:
// Lock this constructor because it does something that isnt thread-safe as per http://stackoverflow.com/questions/16113366/windows-forms-threads-are-losing-their-culture
StreamWriter myStreamWriter;
lock (swConstructorLock) {
myStreamWriter = new StreamWriter(theStreamToWrite);
}
答案 2 :(得分:1)
我发现每个Web请求都调用了CultureInfo.ClearCachedData:/删除它修复了问题。似乎Culture仍然需要某种锁,因为线程A调用ClearCachedData并且线程B请求数据并且它抛出一个空异常。
答案 3 :(得分:0)
我在.NET 3.5应用程序中得到了这个异常(曾经,一次出现蓝色):
System.Threading.SynchronizationLockException: Object synchronization method was called from an unsynchronized block of code.
at System.Globalization.CultureTableRecord.GetCultureTableRecord(String name, Boolean useUserOverride)
at System.Globalization.CultureTableRecord.GetCultureTableRecord(Int32 cultureId, Boolean useUserOverride)
at System.Globalization.CultureInfo..ctor(Int32 culture, Boolean useUserOverride)
at System.Globalization.CultureInfo.GetCultureByLCIDOrName(Int32 preferLCID, String fallbackToString)
at System.Globalization.CultureInfo.InitUserDefaultCulture()
at System.Globalization.CultureInfo.get_UserDefaultCulture()
at System.Threading.Thread.get_CurrentCulture()
at System.Globalization.DateTimeFormatInfo.get_CurrentInfo()
at System.DateTime.ToString(String format)
这发生在锁定的部分,但锁定不是值类型。