Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Background process updating values in a datagrid
Message
De
27/09/2013 09:52:36
 
 
À
27/09/2013 08:48:52
Information générale
Forum:
ASP.NET
Catégorie:
Code, syntaxe and commandes
Versions des environnements
Environment:
C# 4.0
OS:
Windows Server 2012
Network:
Windows 2008 Server
Database:
MS SQL Server
Application:
Web
Divers
Thread ID:
01584125
Message ID:
01584323
Vues:
30
>Viv,
>
>thanks. I'm not sure I understand the problem either :)
>
>My original code was passing off a list of Primary keys to be processed and then the business process was processing those records and I was trying to update the UI whenever each record was processed.
>
>I've changed my code closer to the example you gave so that the looping through the list of primary keys occurs in the UI code and just the actual sending of the email gets sent to the business process. This way I am able to update the data in the grid as a record gets processed. I'm still not terribly happy with what I've done but I'll spend some more time on it before I come back again.

Looping the keys in UI doesn't sound right - doesn't that mean you are creating a new background worker for each email ?
Had to try this so here's a complete example of what I was suggesting:
<Window x:Class="UITest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="321" Width="525">
    <Grid Margin="0,0,0,137">
        <Button Content="Send Emails" Name="btnEmail" Click="BtnEmail_OnClick"  HorizontalAlignment="Left" Margin="32,23,0,0" VerticalAlignment="Top" Width="75"/>
        <ProgressBar Name="progressBar" HorizontalAlignment="Left" Height="13" Margin="71,223,0,-79" VerticalAlignment="Top" Width="394"/>
        <TextBox VerticalScrollBarVisibility="Visible"  Name="txtInfo" HorizontalAlignment="Left" Height="166" Margin="178,23,0,-32" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="147"/>
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System.Windows;

namespace UITest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private BackgroundWorker _backgroundWorker;

        private void BtnEmail_OnClick(object sender, RoutedEventArgs e)
        {
            txtInfo.Text = string.Empty;
            _backgroundWorker = new BackgroundWorker { WorkerReportsProgress = true };
            _backgroundWorker.DoWork += EmailQueueBackgroundWorker_DoWork;
            _backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
            _backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;

            progressBar.Maximum = 100;
            progressBar.Minimum = 0;

            //Dummy list of Primary Keys
            var emailPKs = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

            // Start the Asynch Worker
            _backgroundWorker.RunWorkerAsync(emailPKs);
        }

        private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // Do whatever is ness. to update the UI
            var eEvent = e.UserState as EmailEvent;
            txtInfo.Text += String.Format("Email Id: {0} - {1}{2}", eEvent.EmailId, eEvent.Status.ToString(),
                                               Environment.NewLine);
            progressBar.Value = e.ProgressPercentage;
        }

        void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            txtInfo.Text += "Complete";
            btnEmail.IsEnabled = true;
            progressBar.Value = 100;
        }


        private void EmailQueueBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            var emailPKs = e.Argument as List<int>;
            var worker = sender as BackgroundWorker;

            for (int i = 0; i < emailPKs.Count; i++)
            {
                EmailEvent status = SendEmail(emailPKs[i]);
                //Report back to ui with progress and info on email just sent
                worker.ReportProgress((i*100)/emailPKs.Count,status);
            }
        }

        private EmailEvent SendEmail(int i)
        {
            //Do actual send - I'm just hanging about
            Thread.Sleep(1000);
            //(Faking a status)
            return new EmailEvent {EmailId = i, Status = GetAWeightedStatus()};
        }

        static Random r = new Random();

        private EmailStatus GetAWeightedStatus()
        {
            //Just generating a random status to make it look good :-}
            var distribution = new[] { 1, 2, 0, 0, 0, 0, 0 };
            Array enums = Enum.GetValues(typeof(EmailStatus));
            return (EmailStatus)enums.GetValue(distribution[r.Next(distribution.Length)]);
        }
    }

    public class EmailEvent
    {
        public int EmailId { get; set; }
        public EmailStatus Status { get; set; }
    }

    public enum EmailStatus
    {
        Sent,
        Held,
        Rejected
    }
}
UPDATE: Occurs to me you could set progressBar.Maximum to number of emails and just pass back I rather than calculating a percentage.....
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform