对不起,我的英语不好,如果有人可以帮助我解决问题,我们将不胜感激。
我编写了Windows服务,用于从数据库获取事务并将其导出到平面文件,以通过sftp发送到另一个系统。该服务已运行6个月,没有任何问题。我的代码如下:
我使用了一个名为_isProcessOutwardMessage
的布尔变量来检查线程是否正在运行以启动新线程(processOutwardMessageThread
)。有5个标记和5个这样的线程(但为了使我的帖子简短,我删除了4个)
我的问题是:经过大约6个月的运行,IT人员在服务器中完成了一些工作(他说这已经很坚固了)。自此更新以来,我的服务遇到了错误。当我检查日志时,发现同一线程(例如:processOutwardMessageThread
)已被同时执行两次(看起来该标志不再起作用)。这是错误的,因为它只能在前一个线程完成后运行(标志已设置为false)。
我尝试重新启动该服务,但是它只能在1个小时左右正常运行,之后,它将再次导致错误。请给我一些建议。谢谢
using Timer = System.Timers.Timer;
namespace FastOne.Payment.MessageService
{
internal partial class ProcessMessageService : ServiceBase
{
private Timer _processOutwardMessageTimer;
public ProcessMessageService()
{
InitializeComponent();
}
private void LoadConfiguration()
{
try
{
_processOutwardMessageInterval =
int.Parse(ConfigurationManager.AppSettings["ProcessOutwardMessageInterval"]);
//Running flag
_isProcessOutwardMessage = false;
}
catch (Exception exception)
{
ProcessServiceLogger.Error(exception);
}
}
protected override void OnStart(string[] args)
{
//Load configs
LoadConfiguration();
_processOutwardMessageTimer = new Timer(_processOutwardMessageInterval);
_processOutwardMessageTimer.Elapsed += ProcessOutwardMessageTimer_Elapsed;
_processOutwardMessageTimer.Start();
}
private void ProcessOutwardMessageTimer_Elapsed(object sender, ElapsedEventArgs e)
{
if (!_isProcessOutwardMessage)
{
var processOutwardMessageThread = new Thread(ProcessOutwardMessage);
processOutwardMessageThread.Start();
}
}
private void ProcessOutwardMessage()
{
try
{
ProcessOutwardMessageWithTransaction();
}
catch (Exception exception)
{
ProcessOutwardMessageLogger.Info("FAILED! ROLLBACK TRANSACTION!");
ProcessOutwardMessageLogger.Error(exception);
}
}
private void ProcessOutwardMessageWithTransaction()
{
//Set flag to true
_isProcessOutwardMessage = true;
//Do something here
WriteLogToFile("Thread Execute.");
//Set flag to false
_isProcessOutwardMessage = false;
}
}
}
答案 0 :(得分:1)
您的代码容易出错,因为在竞争条件下存在大量的“机会之窗”。
考虑这种潜在情况:
您的处理执行了两次。
问题是在您检查和设置布尔网守之间的“窗口”太大。检查和设置网守应尽可能接近单个(原子)操作。检查和设定之间的窗口越大,产生比赛状况的可能性越大。
Synchronization objects的创建是为了帮助解决该问题。我建议您将它们合并到您的解决方案中。