I am using string resources from the insert... resx file and satellite assemblies. Are you sure you are naming your files correctly?
Resource1.resx:
<!-- snip-->
<data name="foo" xml:space="preserve">
<value>bar</value>
</data>
Resource1.FR-fr.resx
<--! le snip -->
<data name="foo" xml:space="preserve">
<value>le bar</value>
</data>
Class1.cs :
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Threading;
namespace Frankenstein
{
public class Class1
{
struct LocalizedCallback
{
private WaitCallback localized;
public LocalizedCallback(WaitCallback user)
{
var uiCult = Thread.CurrentThread.CurrentUICulture;
// wrap
localized = (state) =>
{
var tp = Thread.CurrentThread;
var oldUICult = tp.CurrentUICulture;
try
{
// set the caller thread's culture for lookup
Thread.CurrentThread.CurrentUICulture = uiCult;
// call the user-supplied callback
user(state);
}
finally
{
// let's restore the TP thread state
tp.CurrentUICulture = oldUICult;
}
};
}
public static implicit operator WaitCallback(LocalizedCallback me)
{
return me.localized;
}
}
public static void Main(string[] args)
{
AutoResetEvent evt = new AutoResetEvent(false);
WaitCallback worker = state =>
{
Console.Out.WriteLine(Resource1.foo);
evt.Set();
};
// use default resource
Console.Out.WriteLine(">>>>>>>>>>{0}", Thread.CurrentThread.CurrentUICulture);
Console.Out.WriteLine("without wrapper");
ThreadPool.QueueUserWorkItem(worker);
evt.WaitOne();
Console.Out.WriteLine("with wrapper");
ThreadPool.QueueUserWorkItem(new LocalizedCallback(worker));
evt.WaitOne();
// go froggie
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("FR-fr");
Console.Out.WriteLine(">>>>>>>>>>{0}", Thread.CurrentThread.CurrentUICulture);
Console.Out.WriteLine("without wrapper");
ThreadPool.QueueUserWorkItem(worker);
evt.WaitOne();
Console.Out.WriteLine("with wrapper");
ThreadPool.QueueUserWorkItem(new LocalizedCallback(worker));
evt.WaitOne();
}
}
}
Output:
>>>>>>>>>>en-US
without wrapper
bar
with wrapper
bar
>>>>>>>>>>fr-FR
without wrapper
bar
with wrapper
le bar
Press any key to continue . . .
The reason why this works is that the Resource1.Culture property is always set to null, so it falls back to the default (IE Thread.CurrentThread.UICulture).
To prove it, edit the Resource1.Designer.cs file and remove the following attribute from the class:
//[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
Then set a breakpoint in the Resource.Culture property accessors and the foo property accessors, and startup the debugger.
Cheers,
Florian