Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows Forms Threads are losing their culture

We have a .net 3.5 multi-threaded windows forms application. Is is launching 4-5 background workers/ async calls to retrieve data. About 1 in 10 times, one of the threads throws the following error. Sometimes the error is a null exception instead but the same exact call stack. We have tracked the issue down to the thread somehow losing its CultureInfo. Anyone else ran into this?

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)
like image 983
Kenoyer130 Avatar asked Jan 24 '26 03:01

Kenoyer130


2 Answers

Try playing with default culture for entire domain using CultureInfo.DefaultThreadCurrentCulture and/or CultureInfo.DefaultThreadCurrentUICulture and see if that helps. All in all, you'll be able to ensure whether it's related to thread's culture

UPD: that specific exception may be thrown when using sync methods like lock, Monitor, etc on value types, calls to sync methods will box value, creating new one every time. I doubt it could be such serios bug in framework.

Can you check your synchronization code?

UPD2: ok, let's try to debug.

  • First off, turn on break on every exception thrown

  • Next, enable .NET Framework debugging that will help you to locate an error

After that, there is a high chance for a workaround/solution for you problem

like image 156
illegal-immigrant Avatar answered Jan 26 '26 18:01

illegal-immigrant


From just looking at the call stack, this appears to be a framework bug (of sorts). It seems that the StreamWriter constructor is performing a non-thread-safe operation (accessing GetCultureTableRecord) through a complex series of calls. My recommendation would be to serialize your calls to the StreamWriter constructor:

// Put this somewhere convenient
public static Object swConstructorLock = new Object();

then, when you create your 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);
}
like image 30
Chris Shain Avatar answered Jan 26 '26 18:01

Chris Shain