Windows窗体线程正在失去它们的文化

本文关键字:文化 失去 窗体 线程 Windows | 更新日期: 2023-09-27 18:10:01

我们有一个。net 3.5多线程windows窗体应用程序。它正在启动4-5个后台工作者/异步调用来检索数据。大约每10次就有1次,其中一个线程抛出以下错误。有时错误是空异常,而不是相同的调用堆栈。我们已经追踪到这个问题,因为线程不知何故丢失了它的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)

Windows窗体线程正在失去它们的文化

尝试使用CultureInfo.DefaultThreadCurrentCulture和/或CultureInfo.DefaultThreadCurrentUICulture为整个域设置默认区域性,看看是否有帮助。总而言之,您将能够确保它是否与线程的文化

相关。

UPD:当使用同步方法如lock, Monitor等对值类型时可能会抛出特定的异常,调用同步方法将框值,每次创建一个新的。我怀疑这可能是框架中如此严重的错误。

你能检查你的同步代码吗?

UPD2 :好的,让我们试着调试

  • 首先,在抛出每个异常时打开break

  • 下一步,启用。net框架调试,这将帮助您定位错误

在那之后,你的问题就很有可能得到解决

从调用堆栈来看,这似乎是一个框架错误(某种程度上)。看起来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);
}

我找到了CultureInfo。cleararchacheddata在每个web请求中都被调用:/删除该问题修复了。似乎文化仍然需要某种锁,因为线程A调用ClearCachedData和线程B请求数据,它抛出一个空异常。

我得到了这个异常(一次,out of a blue),也是在一个。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)

这个错误发生在一个被锁定的区域,但是这个锁不是一个值类型