Использование таймера в пуле потоков - PullRequest
0 голосов
/ 04 марта 2011

Я разрабатываю Windows-приложение для своей компании, которое работает на сервере.Это многопоточное приложение, и для этого я использую Thread Pool.

Модуль электронной почты моего приложения состоит из 3 основных методов.Первый метод получает новые кампании из базы данных, второй метод решает, кому кампания будет отправлена ​​по электронной почте, а третий метод отправляет ее.

Когда я запускаю приложение, первый метод переходит в пул потоков, если естьновая кампания, 2-й метод вызывается с информацией о кампании.Но пока все это происходит, первый метод должен проверять базу данных каждые три секунды, если новая кампания или нет.

Я не уверен, должен ли я использовать класс System.Windows.Forms.Timer длятот или System.Threading.Timer ??

И я не уверен, как это реализовать?Собираюсь ли я использовать функцию вызова для вызова потока за пределами основного интерфейса?Не могли бы вы опубликовать пример кода и предложить лучшие практики?Большое спасибо

Вот мой код:

private void btnStart_MouseClick(object sender, MouseEventArgs e)
    {
        smartThreadPool = new SmartThreadPool();
        workItemGroup = smartThreadPool.CreateWorkItemsGroup(1);
        workItemGroup.QueueWorkItem(CheckNewCampaigns);
        //smartThreadPool.QueueWorkItem(new WorkItemCallback(this.CheckNewCampaigns));            
    }

    private object CheckNewCampaigns(object state) // 1st method
    {
        StringBuilder builder = new StringBuilder();
        IEnumerable<Campaigns> CampaignsList = DatabaseManager.GetCampaignsList(DatabaseManager.GetNewCampaigns());

        foreach (Campaigns Campaign in CampaignsList)
        {
            builder.AppendFormat("New Campaign Arrived($) --> {0}\r\n", DateTime.Now.ToLongTimeString());
            builder.AppendFormat("CampaignID              --> {0}\r\n", Campaign.CampaignID);
            builder.AppendFormat("CustomerID              --> {0}\r\n", Campaign.CustomerID);
            builder.AppendFormat("ClientID                --> {0}\r\n", Campaign.ClientID);
            builder.AppendFormat("Title                   --> {0}\r\n", Campaign.Title);
            builder.AppendFormat("Subject                 --> {0}\r\n", Campaign.Subject);
            builder.AppendFormat("Status              --> {0}\r\n", Campaign.Status);
        }

        Console.WriteLine(builder.ToString());

        workItemGroup.QueueWorkItem(new WorkItemCallback(this.PrepareCampaignEmail), 2);
        return true;
    }

    private object PrepareCampaignEmail(object CampaignID)  // Second Method
    {
        int campaignID = (int)CampaignID;
        IEnumerable<Campaigns> CampaignDetailsList = DatabaseManager.GetCampaignsList(DatabaseManager.GetCampaignDetails(campaignID)); // bir tane campaign gelmekte
        IEnumerable<Subscribers> SubscribersList = DatabaseManager.GetCampaignSubscribersList(DatabaseManager.GetCampaignSubscribers(campaignID));
        ArrayList test = new ArrayList();

        DataTable dtCustomValuesForCampaign = DatabaseManager.GetCustomValuesForCampaign(campaignID);

        foreach (Subscribers subscriber in SubscribersList)
        {
            workItemGroup.QueueWorkItem(new WorkItemCallback(this.SendEmail), subscriber.Email);
        }

        return true;
    }

Ответы [ 3 ]

1 голос
/ 04 марта 2011

В вашей ситуации, поскольку это приложение Windows Forms, и вы, возможно, захотите обновить пользовательский интерфейс в обработчике событий таймера, я бы предложил использовать Windows.Forms.Timer.

Использовать Windows.Forms.Timer довольно просто. В режиме конструктора формы выберите Timer на панели инструментов и поместите его в форму. Затем нажмите на него, чтобы установить свойства. Вы хотите установить Interval на 3000 (это 3000 миллисекунд) и Enabled на False.

На вкладке События дважды щелкните событие Tick, и среда IDE создаст для вас обработчик. Вы хотите, чтобы обработчик событий выглядел примерно так:

private void timer1_Tick(object sender, EventArgs e)
{
    var stateObj = // create your state object here
    CheckNewCampaigns(stateObj);
}

Вам нужно будет запустить таймер (установите Enabled на True). Вы можете сделать это в обработчике событий Create или включить его, когда пользователь нажмет кнопку «Пуск». Вы также можете остановить его в любое время, установив Enabled в False.

1 голос
/ 04 марта 2011

System.Thread.Timer и Windows.Forms.Timer действуют по-разному.

System.Thread.Timer будет работать в потоке system .Он имеет внутренний пул потоков, поэтому он не будет запускаться в одном из потоков, которые вы явно создали.Каждый интервал один из потоков в пуле таймера будет запускать обратный вызов, с которым вы инициализировали объект.

Windows.Forms.Timer вызовет событие Tick в потоке current и будетделайте это каждый интервал, пока не отключите его.

Я не могу сказать вам, что больше подходит для вашей ситуации;это зависит от того, хотите ли вы запустить таймер в потоке пользовательского интерфейса, а также от других факторов.

0 голосов
/ 26 января 2012

Попробуйте это:

public void EnableTimer()
        {
            if (this.InvokeRequired)
                this.Invoke(new Action(EnableTimer));
            else
                this.timer1.Enabled = true;
        }
...