I have a method which will be called inside a thread and those threads are managed by threadpool. The method is calling a DLL's method which unfortunately requires a specific locale for being performed correctly.
Before puting this method to be ran by threadpool, I've tested it while running in application's main thread and also while I manually manage the threads and it works fine, but when I put it into work inside a threadpool, locale is not applied and consequently the method does not behave correctly.
Here is the part of the method which should be affected by locale change (but not behave well):
CultureInfo before = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo("fa-IR");
int result = tsms.SendSMS(smsTask.MobileNumber.MobileNumberInString, smsTask.Message);
Thread.CurrentThread.CurrentUICulture = before;
and here is the threadpool creating structure:
foreach (SMSTask smsTask in tasksList)
{
if (this.threadsCount < this.threadPoolSize)
{
this.threadsCount++;
ThreadPool.QueueUserWorkItem(new WaitCallback(SendMessage), (object)smsTask);
}
}
I also tried setting locale to thread object like below but it didn't solve the problem: (line 2 and 3):
threadObject = new Thread(new ThreadStart(TaskProcessingThreadFunction));
threadObject.CurrentCulture = new CultureInfo("fa-IR");
threadObject.CurrentUICulture = new CultureInfo("fa-IR");
threadObject.Start();
Please guide me on how should I get the correct result while this method is being ran inside threadpool.
Updated Version:
this.isTerminated = false;
Thread.Sleep(1000);
while (!this.isTerminated)
{
Thread.Sleep(1000);
IList<SMSTask> tasksList = dataProvider.GetTasks(this.minimumRetryTimeInSeconds);
if (tasksList == null || tasksList.Count < 1)
continue;
singleTaskConsoleObject(" " + tasksList.Count + " task(s) fetched for sending.");
var cultureToUse = new System.Globalization.CultureInfo("fa-IR");
var currentThread = System.Threading.Thread.CurrentThread;
currentThread.CurrentCulture = cultureToUse;
currentThread.CurrentUICulture = cultureToUse;
var currentIdentity = System.Security.Principal.WindowsIdentity.GetCurrent();
foreach (SMSTask smsTask in tasksList)
{
if (this.threadsCount < this.threadPoolSize)
{
this.threadsCount++;
smsTask.Iden = currentIdentity;
ThreadPool.QueueUserWorkItem(new WaitCallback(SendMessage), (object)smsTask);
}
}
while (this.threadsCount > 0)
Thread.Sleep(50);
}
Other Methods:
private void SendMessage(object smsTask)
{
System.Security.Principal.WindowsImpersonationContext impersonationContext = null;
try
{
SMSTask smsTaskEntity = (SMSTask)smsTask;
impersonationContext = ((System.Security.Principal.WindowsIdentity)(smsTaskEntity.Iden)).Impersonate();
SmsSender smsSender = new SmsSender();
SMSSendingResponse response = smsSender.SendSMS(smsTaskEntity);
bool loggingResult = dataProvider.UpdateResponse(response);
singleTaskGridObject(response, loggingResult);
this.threadsCount--;
}
finally
{
if (impersonationContext != null)
{
impersonationContext.Undo();
}
}
}
And this separate class:
public SMSSendingResponse SendSMS(SMSTask smsTask)
{
TSMSLIB_TLB.TSMS_Tooba tsms = new TSMS_Tooba();
SendingResult sendingResult = SendingResult.Initial_Condition;
try
{
System.Globalization.CultureInfo before = System.Threading.Thread.CurrentThread.CurrentCulture;
System.Threading.Thread.CurrentThread.CurrentCulture =
new System.Globalization.CultureInfo("fa-IR");
string msg = string.Format(System.Threading.Thread.CurrentThread.CurrentCulture, smsTask.Message);
int result = tsms.SendSMS(smsTask.MobileNumber.MobileNumberInString, msg);
System.Threading.Thread.CurrentThread.CurrentUICulture = before;
if (result > 0)
{
return new SMSSendingResponse(smsTask, SMSDeclarations.SendingStatus.SentSuccessfully, result.ToString());
}
else
{
foreach (SendingResult sResult in Enum.GetValues(typeof(SendingResult)))
{
if (result == (int)sResult)
{
sendingResult = sResult;
}
}
return new SMSSendingResponse(smsTask, SMSDeclarations.SendingStatus.SendingFailed,
result.ToString(), sendingResult.ToString());
}
}
catch (Exception ex)
{
return new SMSSendingResponse(smsTask, SMSDeclarations.SendingStatus.SendingFailed,
"0".ToString(), "Exception occured");
}
}
Dispatcher
– ImaginativeThread.CurrentThread.CurrentCulture
insideTaskProcessingThreadFunction
...? – LookSendSMS
most likely fires off something on another thread which won't be using the same culture of the calling thread? (unless it's being set internally). You don't provide any implementation detail of that method so can't say for sure, but I presume that is what the problem is. – Boyce