gpt4 book ai didi

c# - Thread.CurrentThread.CurrentCulture 在线程池内的线程中不工作

转载 作者:太空狗 更新时间:2023-10-29 21:54:15 24 4
gpt4 key购买 nike

我有一个将在线程内调用的方法,这些线程由线程池管理。该方法正在调用 DLL 的方法,不幸的是,该方法需要特定的语言环境才能正确执行。

在将此方法由线程池运行之前,我已经在应用程序的主线程中运行以及手动管理线程时对其进行了测试并且它工作正常,但是当我将其放入线程池中时,语言环境是未应用,因此该方法无法正常运行。

这是方法中应该受区域设置更改影响的部分(但表现不佳):

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;

这是线程池创建结构:

foreach (SMSTask smsTask in tasksList)
{
if (this.threadsCount < this.threadPoolSize)
{
this.threadsCount++;
ThreadPool.QueueUserWorkItem(new WaitCallback(SendMessage), (object)smsTask);
}
}

我也试过像下面这样将语言环境设置为线程对象,但它没有解决问题:(第 2 行和第 3 行):

threadObject = new Thread(new ThreadStart(TaskProcessingThreadFunction));
threadObject.CurrentCulture = new CultureInfo("fa-IR");
threadObject.CurrentUICulture = new CultureInfo("fa-IR");
threadObject.Start();

请指导我如何在线程池中运行此方法时获得正确的结果。

更新版本:

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);
}

其他方法:

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();
}
}
}

还有这个单独的类:

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");
}

}

最佳答案

文化必须在线程调用的实际方法中应用。

一个简单的方法应该是将要在线程池上执行的方法包装在另一个方法中,该方法在执行原始方法之前将 CultureInfo 从将作业排队的线程应用到线程池线程,类似;

private static WaitCallback PropagateCulture(WaitCallback action)
{
var currentCulture = Thread.CurrentThread.CurrentCulture;
var currentUiCulture = Thread.CurrentThread.CurrentUICulture;
return (x) =>
{
Thread.CurrentThread.CurrentCulture = currentCulture;
Thread.CurrentThread.CurrentUICulture = currentUiCulture;
action(x);
};
}

鉴于该方法,您只需提交给线程池使用;

ThreadPool.QueueUserWorkItem(PropagateCulture(SendMessage), (object)smsTask);

(感谢 Aidiakapi 在下面的评论中指出 WaitCallback)

关于c# - Thread.CurrentThread.CurrentCulture 在线程池内的线程中不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20872028/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com