Windows Forms Threads正在失去他们的文化

时间:2013-04-19 20:56:30

标签: c# multithreading winforms

我们有一个.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)

4 个答案:

答案 0 :(得分:1)

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

UPD :在值类型上使用lockMonitor等同步方法时,可能会抛出该特定异常,调用同步方法将设置值,每次创建新值。我怀疑它可能是框架中的这种严重错误。

您可以查看同步代码吗?

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

之后,很有可能为您解决问题的解决方法/解决方案

答案 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)

这发生在锁定的部分,但锁定不是值类型。