2

私はc#テクノロジを使用してasp.net 2.0でWebサイトを作成しました。また、管理者制御部分に1種類のニュースレターアプリケーションを含めました。Add_CodeディレクトリにJobRunner.csクラスの1つがある場合。

実際、私の問題はニュースレターの申し込みで仕事を始めることでした。詳細については、ファイルcs.codeとJobRunner.csクラスの完全なコードも含めます。

  • これは、ジョブIDを開始ジョブに設定するための私のmanage_jobs.aspx.csコーディングです。

    protected void lbut_startjob_Click(object sender, EventArgs e)
    {
        int count = 0;
        SetData();
        GV_ViewJobs.AllowPaging = false;
        this.FillGrid();
        ArrayList arr = (ArrayList)ViewState["SelectedRecords"];
        count = arr.Count;
        for (int i = 0; i < GV_ViewJobs.Rows.Count; i++)
        {
            if (arr.Contains(GV_ViewJobs.DataKeys[i].Value))
            {
                StartJob(GV_ViewJobs.DataKeys[i].Value.ToString());
                arr.Remove(GV_ViewJobs.DataKeys[i].Value);
            }
        }
        ViewState["SelectedRecords"] = arr;
        hfCount.Value = "0";
        GV_ViewJobs.AllowPaging = true;
        this.FillGrid();
        ShowMessageRun(count);
    }
    private void StartJob(string JobID)
    {
        int jobId = Convert.ToInt32(JobID);
        if (!JobRunner.IsJobQueuedOrRunning(jobId))
        {
            JobRunner.RunJob(jobId);
        }
    }
    
  • および私のJobRunner.csクラス(すべてのコーディング)

JobRunner.cs ----------------------------------------------- --------

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using System.Collections.Generic;
    using System.Data.SqlClient;
    using System.Text;
    using System.IO;
    using System.Net.Mail;
    using System.Threading;
    /// <summary>
    /// Summary description for JobRunner
    /// </summary>
    public static class JobRunner
    {
        private static List<JobInfo> ActiveJobs = new List<JobInfo>();
        //public static JobRunner()
        //{
        //    //
        //    // TODO: Add constructor logic here
        //    //
        //}
        public static void RunJob(int jobId)
        {
            lock (ActiveJobs)
            {
                JobInfo jobInfo = FindQueuedOrRunningJob(jobId);

                if (jobInfo != null)
                    return;

                jobInfo = FindExitedJob(jobId);

                if (jobInfo == null)
                {
                    jobInfo = new JobInfo(jobId);
                    ActiveJobs.Add(jobInfo); // Default status is Queued
                }
                else
                {
                    jobInfo.State = JobInfo.JobState.Queued;
                }

                ThreadPool.QueueUserWorkItem(new WaitCallback(StartJob), jobInfo);
            }
        }
        public static bool IsJobQueuedOrRunning(int jobId)
        {
            return FindQueuedOrRunningJob(jobId) != null;
        }
        public static JobInfo FindJob(int jobId)
        {
            JobInfo ji = FindQueuedOrRunningJob(jobId);

            if (ji != null)
                return ji;

            return FindExitedJob(jobId);
        }
        public static JobInfo FindQueuedOrRunningJob(int jobId)
        {
            lock (ActiveJobs)
            {
                for (int i = 0; i < ActiveJobs.Count; i++)
                {
                    JobInfo ji = ActiveJobs[i];
                    if (ji.JobId == jobId && (ji.State == JobInfo.JobState.Queued | ji.State == JobInfo.JobState.Running))
                        return ji;
                }

                return null;
            }
        }
        public static JobInfo FindExitedJob(int jobId)
        {
            lock (ActiveJobs)
            {
                for (int i = 0; i < ActiveJobs.Count; i++)
                {
                    JobInfo ji = ActiveJobs[i];

                    if (ji.JobId == jobId && ji.State == JobInfo.JobState.Exited)
                        return ji;
                }

                return null;
            }
        }
        public static void StartJob(object stateInfo)
        {
            JobInfo jobInfo = (JobInfo)stateInfo;
            int jobId = jobInfo.JobId;
            jobInfo.State = JobInfo.JobState.Running;
            // Email settings
            string fromName = ConfigurationManager.AppSettings["Newsletter_FromName"];
            string fromEmailAddress = ConfigurationManager.AppSettings["Newsletter_FromEmailAddress"];
            SmtpClient client = Util.GetSmtpClient();
            // For logging
            int emailsSentInThisAttempt = 0;
            try
            {
                using (SqlConnection con = Util.GetConnection())
                {
                    con.Open();
                    jobInfo.Log(con, "Connected to database...");
                    // Step 1: Retrieving job information
                    string subject, plainText;
                    DatabaseHelper.GetJobInfo(con, jobInfo.JobId, out subject, out plainText);
                    jobInfo.Log(con, String.Format("Retrieved job #{0} information...", jobId));
                    // Creating a loop to send all emails one-by-one
                    while (true)
                    {
                        // Step 2: Retrieving one email from the list
                        // to whom this email will be sent
                        //int subscriberId;
                        string email;
                        //int validationCode;

                        //DatabaseHelper.PopAllotedEmail(con, jobId, out subscriberId,out email, out validationCode);
                        DatabaseHelper.PopAllotedEmail(con, jobId, out email);
                        if (email == null)
                            break;

                        // Step 3: Sending email
                        try
                        {
                            //SendEmail(fromName, fromEmailAddress, email, subject, plainText, client, subscriberId,validationCode);
                            SendEmail(fromName, fromEmailAddress, email, subject, plainText, client);
                        }
                        catch (Exception ex)
                        {
                            DatabaseHelper.PushAllotedEmail(jobId, email);
                            jobInfo.Log(con,
                        String.Format("Could not send email to: {0}",
                            email));

                            throw ex;
                        }

                        emailsSentInThisAttempt++;
                    }

                    DatabaseHelper.SetJobCompleted(con, jobId, DateTime.Now);
                    jobInfo.Log(con, "Successfully delivered " +
                emailsSentInThisAttempt + " email(s).");
                    jobInfo.Log(con, "Exiting with success!");
                }
            }
            catch (Exception ex)
            {
                jobInfo.Log("Exception: " + ex.Message);
                jobInfo.Log("Exiting with disgrace!");
            }
            finally
            {
                jobInfo.State = JobInfo.JobState.Exited;
            }
        }
        private static void SendEmail(string fromName, string fromEmailAddress, string toEmailAddress, string subject, string plainText, SmtpClient client)
        {
            MailMessage msg = new MailMessage();
            msg.IsBodyHtml = true;
            client.EnableSsl = true;
            if (fromName != null)
                msg.From = new MailAddress(fromName + " <" + fromEmailAddress + ">");
            else
                msg.From = new MailAddress(fromEmailAddress);
            msg.To.Add(new MailAddress(toEmailAddress));
            msg.Subject = subject;
            string pathToApp = ConfigurationManager.AppSettings["Newsletter_PathToApplication"];
            string unsubscribeText = "<br/>\r\n\r\n---------------------------\r\n" +
                                     "To unsubscribe, please click the following link:\r\n" +
                                     pathToApp + "Unsubscribe.aspx";
            msg.Body = plainText + unsubscribeText;
            client.Send(msg);
        }
        public class JobInfo
        {
            public enum JobState { Queued, Running, Exited }
            public int JobId
            {
                get
                {
                    return JobId;
                }
                set
                {
                    JobId = value; // <- Exception occurred here.
                }
            }
            public JobState State
            {
                get
                {
                    return State;
                }
                set
                {
                    State = value;
                }
            }
            public JobInfo(int jobId)
            {
                JobId = jobId;
                State = JobState.Queued;
            }
            public void Log(string message)
            {
                DatabaseHelper.AddLogMessage(JobId, DateTime.Now, message);
            }
            public void Log(SqlConnection con, string message)
            {
                DatabaseHelper.AddLogMessage(con, JobId, DateTime.Now, message);
            }
            public override bool Equals(object obj)
            {
                if (obj is JobInfo)
                {
                    JobInfo otherJobInfo = (JobInfo)obj;
                    if (JobId == otherJobInfo.JobId && State == otherJobInfo.State)
                        return true;
                }
                return false;
            }
        }
    }

例外:

「System.StackOverflowExceptionが未処理でした。App_Code.okrls50x.dllでタイプ「System.StackOverflowException」の未処理の例外が発生しました。」

  • コンパイル時に「'JobRunner.JobInfo'はObject.Equals(object o)をオーバーライドしますが、Object.GetHashCode()はオーバーライドしません」のような警告メッセージも1つ表示されるかどうか

JobInfoメソッドのGetSetPropertiesに問題があるのを助けてください?...

4

3 に答える 3

3

これらのプロパティの1つにより、StackOverflowExceptionが発生しました。

public int JobId
            {
                get
                {
                    return JobId;
                }
                set
                {
                    JobId = value; 
                }
            }
            public JobState State
            {
                get
                {
                    return State;
                }
                set
                {
                    State = value;
                }
            }

プロパティは次のように実装できます(自動実装):

public int JobId { get; set; }

または、バッキングフィールドを使用して手動で実装することもできます。

private int _jobId;
public int JobId
{
    get { return _jobId; }
    set { _jobId = value; }
}
于 2012-04-12T14:41:47.213 に答える
1

問題は、コードのどこかにプロパティがあることです

JobState State 
{ 
   get { return State; } 
   set { State = value; } //THIS LINE RUNS in STACKOVERFLOW 
}

この宣言変数JobStateを修正するには、次のようにします。

private JobState state;
public JobState State 
{ 
     get { return state; } 
     set { state= value; } 
 }
于 2012-04-12T14:38:38.930 に答える
0
public JobState State
            {
                get
                {
                    return State;
                }
                set
                {
                    if(value != State)
                    {
                       State = value;
                    }
                }
            }
于 2012-04-12T14:42:55.697 に答える