首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程在HttpApplication中卡住

线程在HttpApplication中卡住
EN

Stack Overflow用户
提问于 2013-12-13 03:34:01
回答 1查看 178关注 0票数 0

我有一个从Global.asax文件启动的WCF应用程序,有一个应用程序启动事件,代码如下:

代码语言:javascript
复制
    public class Global : HttpApplication
    {
        private bool isInitialized = false;
        private static readonly ILog log = LogManager.GetLogger(typeof(Global));
        private PushController pushController;
        private Task pushMonitoringTask;

        protected void Application_Start(object sender, EventArgs e)
        {
            Initialize();
            pushMonitoringTask = Task.Run(() => pushController.StartMonitoring());
        }
 ...}

推送控制器:

代码语言:javascript
复制
    public class PushController
    {
        private IRepository<Question> QuestionRepository { get; set; }
        private IRepository<Mobile_Report> ReportRepository { get; set; }

        private readonly string _syncFilePath;

        private readonly string certificatePath;

        private readonly PushBroker _broker;

        private bool _isStopRequired;

        public PushController(IRepository<Question> questionRepository, IRepository<Mobile_Report> reportsRepository, HttpServerUtility server)
        {
            QuestionRepository = questionRepository;
            ReportRepository = reportsRepository;

            _broker = new PushBroker();

            _syncFilePath = server.MapPath("~/SyncFile.txt");
            certificatePath = "My cert path";

            if (!File.Exists(_syncFilePath))
            {
                using (StreamWriter sw = File.AppendText(_syncFilePath))
                {
                    sw.WriteLine(DateTime.Now);
                    sw.Flush();
                }
            }

            _isStopRequired = false;
        }

        public void StartMonitoring()
        {
            var delay = Convert.ToInt32(ConfigurationManager.AppSettings["NewQuestionsMonitoringDelay"]);
            RunPushServices();

            while (!_isStopRequired)
            {
                using (var fileStream = new FileStream(_syncFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
                {
                    DateTime lastSyncDate;

                    using (var sw = new StreamReader(fileStream))
                    {
                        lastSyncDate = Convert.ToDateTime(sw.ReadLine());
                    }

                    if (lastSyncDate == default(DateTime))
                    {
                        throw new Exception("Corrupted or missing sync date");
                    }

                    EnqueueNotificationsList(lastSyncDate);

                    using (var sw = new StreamWriter(_syncFilePath, false))
                    {
                        sw.WriteLine(DateTime.Now);
                        sw.Flush();
                    }
                }

                Thread.Sleep(delay * 1000);
            }

            //_broker.StopAllServices();//waits for the queue to drain
        }

        private void RunPushServices()
        {
            _broker.RegisterAppleService(new ApplePushChannelSettings(false, certificatePath, "My cert password"));
            //_broker.RegisterGcmService(new GcmPushChannelSettings("senderId", "sender auth token", "android app package name"));
        }

        private void EnqueueNotificationsList(DateTime lastSyncDate)
        {
            var newQuestions = QuestionRepository.GetAll().Where(q => q.UtcDateCreated >= lastSyncDate);
            var newReports = ReportRepository.GetAll().Where(r => r.CreatedDate >= lastSyncDate);

            EnqueueQuestionsNotifications(newQuestions);
            EnqueueReportsNorifications(newReports);
        }

        private void EnqueueQuestionsNotifications(IEnumerable<Question> newQuestions)
        {
            foreach (var questionGroup in newQuestions.GroupBy(q => q.Mobile_Sample))
            {
                var firstQuestion = questionGroup.First();
                var targetSample = firstQuestion.Mobile_Sample;
                var allSessions = firstQuestion.Mobile_Sample.Mobile_Claim.Mobile_Contact.UserSession;

                var questionsNotificationString = BuildQuestionsNotificationString(targetSample, questionGroup.Count());

                foreach (var userSession in allSessions)
                {
                    switch (userSession.DeviceType)
                    {
                        case (int)DeviceType.IOSDeivce:
                            _broker.QueueNotification(new AppleNotification()
                                .ForDeviceToken(userSession.DeviceToken)
                                .WithAlert(questionsNotificationString)
                                .WithBadge(1)
                                .WithSound("default")
                                .WithCustomItem("PushInfo", "Questions", targetSample.ID));
                            break;
                        //case (int)DeviceType.AndroidDevice:
                        //    _broker.QueueNotification(
                        //        new GcmNotification().ForDeviceRegistrationId(userSession.DeviceToken)
                        //            .WithJson(@"{""alert"":""ITEL Questions"",""badge"":7,""sound"":""sound.caf""}");
                        //    break;
                    }
                }
            }
        }

        private void EnqueueReportsNorifications(IEnumerable<Mobile_Report> newReports)
        {
            foreach (var reportsGroup in newReports.GroupBy(q => q.Mobile_Sample))
            {
                var firstReport = reportsGroup.First();
                var targetSample = firstReport.Mobile_Sample;
                var allSessions = firstReport.Mobile_Sample.Mobile_Claim.Mobile_Contact.UserSession;

                var reportNotificationString = BuildReportNotificationString(targetSample);

                foreach (var userSession in allSessions)
                {
                    switch (userSession.DeviceType)
                    {
                        case (int)DeviceType.IOSDeivce:
                            _broker.QueueNotification(new AppleNotification()
                                .ForDeviceToken(userSession.DeviceToken)
                                .WithAlert(reportNotificationString)
                                .WithBadge(1)
                                .WithSound("default")
                                .WithCustomItem("Target", "Reports", targetSample.ID));
                            break;
                        //case (int)DeviceType.AndroidDevice:
                        //    _broker.QueueNotification(
                        //        new GcmNotification().ForDeviceRegistrationId(userSession.DeviceToken)
                        //            .WithJson(@"{""alert"":""ITEL Questions"",""badge"":7,""sound"":""sound.caf""}");
                        //    break;
                    }
                }
            }
        }

        private string BuildQuestionsNotificationString(Mobile_Sample targetSample, int count)
        {
            var claimLastNameString = !string.IsNullOrEmpty(targetSample.Mobile_Claim.IILastName)
                ? " " + targetSample.Mobile_Claim.IILastName
                : string.Empty;


            var claimNumberString = !string.IsNullOrEmpty(targetSample.Mobile_Claim.ClaimNumber)
                ? " Claim #" + targetSample.Mobile_Claim.ClaimNumber + ", "
                : " Claim # -";

            var areaDamagedString = !string.IsNullOrEmpty(targetSample.AreaDamaged)
                ? " (" + targetSample.AreaDamaged + ")"
                : string.Empty;

            return "You have " + count + " new questions for" + claimLastNameString + claimNumberString + targetSample.Mobile_SampleType.Name + areaDamagedString;
        }

        private string BuildReportNotificationString(Mobile_Sample targetSample)
        {
            var claimLastNameString = !string.IsNullOrEmpty(targetSample.Mobile_Claim.IILastName)
                ? " " + targetSample.Mobile_Claim.IILastName
                : string.Empty;


            var claimNumberString = !string.IsNullOrEmpty(targetSample.Mobile_Claim.ClaimNumber)
                ? " Claim #" + targetSample.Mobile_Claim.ClaimNumber + ", "
                : " Claim # -";

            var areaDamagedString = !string.IsNullOrEmpty(targetSample.AreaDamaged)
                ? " (" + targetSample.AreaDamaged + ")"
                : string.Empty;

            return "You have a new report for" + claimLastNameString + claimNumberString + targetSample.Mobile_SampleType.Name + areaDamagedString;
        }

        public void RequestMonitoringStop()
        {
            _isStopRequired = true;
        }
    }

如你所见,我正在启动一个后台任务,它在Global.asax中的Application_End上终止。问题是,线程周期性地被卡住,不再继续运行(可能,无声地崩溃或其他什么),所以SyncFile不会更新,也不会向客户端推送新的通知,服务器的主要功能仍然在运行,这也是一个棘手的问题-我不能在本地重现问题,它只在服务器部署到生产服务器时出现,也许HttpApplication中有一些关于任务的陷阱,或者我遗漏了什么?提前谢谢。

EN

回答 1

Stack Overflow用户

发布于 2013-12-13 08:17:25

找到了解决方案-如果站点进入“空闲”状态,如果20分钟(默认情况下)没有请求,则必须编辑IIS设置。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20552558

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档