첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

▶ Data.cs

using System;
using System.Collections.Generic;

namespace HowToParallelizeDataIntensiveOperationsOnInMemoryData
{
    /// <summary>
    /// 데이터
    /// </summary>
    public static class Data
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 고객 리스트
        /// </summary>
        private static List<string> customerList;

        /// <summary>
        /// 제품 리스트
        /// </summary>
        private static List<KeyValuePair<string, decimal>> productList;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 고객 리스트 - CustomerList

        /// <summary>
        /// 고객 리스트
        /// </summary>
        public static List<string> CustomerList
        {
            get
            {
                if(this.customerList == null)
                {
                    this.customerList = new List<string>();

                    this.customerList.AddRange
                    (
                        new string[]
                        {
                            "Maria Anders"      , "Ana Trujillo"       , "Antonio Moreno"    , "Thomas Hardy"        ,
                            "Christina Berglund", "Hanna Moos"         , "Frédérique Citeaux"  , "Martín Sommer"        ,
                            "Laurence Lebihan"  , "Elizabeth Lincoln"  , "Victoria Ashworth" , "Patricio Simpson"    ,
                            "Francisco Chang"   , "Yang Wang"          , "Pedro Afonso"      , "Elizabeth Brown"     ,
                            "Sven Ottlieb"      , "Janine Labrune"     , "Ann Devon"         , "Roland Mendel"       , 
                            "Aria Cruz"         , "Diego Roel"         , "Martine Rancé"      , "Maria Larsson"       , 
                            "Peter Franken"     , "Carine Schmitt"     , "Paolo Accorti"     , "Lino Rodriguez "     ,
                            "Eduardo Saavedra"  , "José Pedro Freyre"   , "André Fonseca"      , "Howard Snyder"       ,
                            "Manuel Pereira"    , "Mario Pontes"       , "Carlos Hernández"   , "Yoshi Latimer"       ,
                            "Patricia McKenna"  , "Helen Bennett"      , "Philip Cramer"     , "Daniel Tonini"       ,
                            "Annette Roulet"    , "Yoshi Tannamuri"    , "John Steel"        , "Renate Messner"      , 
                            "Jaime Yorres"      , "Carlos González"     , "Felipe Izquierdo"  , "Fran Wilson"         , 
                            "Giovanni Rovelli"  , "Catherine Dewey"    , "Jean Fresnière"     , "Alexander Feuer"     , 
                            "Simon Crowther"    , "Yvonne Moncada"     , "Rene Phillips"     , "Henriette Pfalzheim" , 
                            "Marie Bertrand"    , "Guillermo Fernández" , "Georg Pipps"       , "Isabel de Castro"    ,
                            "Bernardo Batista"  , "Lúcia Carvalho"      , "Horst Kloss"       , "Sergio Gutiérrez"     , 
                            "Paula Wilson"      , "Maurizio Moroni"    , "Janete Limeira"    ,"Michael Holz"         , 
                            "Alejandra Camino"  , "Jonas Bergulfsen"   , "Jose Pavarotti"    , "Hari Kumar"          , 
                            "Jytte Petersen"    , "Dominique Perrier"  , "Art Braunschweiger", "Pascale Cartrain"    , 
                            "Liz Nixon"         , "Liu Wong"           , "Karin Josephs"     , "Miguel Angel Paolino", 
                            "Anabela Domingues" , "Helvetius Nagy"     , "Palle Ibsen"       , "Mary Saveley"        , 
                            "Paul Henriot"      , "Rita Müller"         , "Pirkko Koskitalo"  , "Paula Parente"       , 
                            "Karl Jablonski"    , "Matti Karttunen"    , "Zbyszek Piestrzeniewicz"
                        }
                    );
                }

                return this.customerList;
            }
        }

        #endregion

        #region 제품 리스트 - ProductList

        /// <summary>
        /// 제품 리스트
        /// </summary>
        public static List<KeyValuePair<string, decimal>> ProductList
        {
            get
            {
                if(this.productList == null)
                {
                    this.productList = new List<KeyValuePair<string, decimal>>();

                    this.productList.Add(new KeyValuePair<string,decimal>("Chai"                            , 18.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Chang"                           , 19.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Aniseed Syrup"                   , 10.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Chef Anton's Cajun Seasoning"    , 22.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Chef Anton's Gumbo Mix"          , 21.35m ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Grandma's Boysenberry Spread"    , 25.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Uncle Bob's Organic Dried Pears" , 30.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Northwoods Cranberry Sauce"      , 40.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Mishi Kobe Niku"                 , 97.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Ikura"                           , 31.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Queso Cabrales"                  , 21.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Queso Manchego La Pastora"       , 38.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Konbu"                           , 6.0m   ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Tofu"                            , 23.25m ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Genen Shouyu"                    , 15.5m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Pavlova"                         , 17.45m ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Alice Mutton"                    , 39.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Carnarvon Tigers"                , 62.5m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Teatime Chocolate Biscuits"      , 9.2m   ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Sir Rodney's Marmalade"          , 81.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Sir Rodney's Scones"             , 10.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Gustaf's Knäckebröd"               , 21.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Tunnbröd"                         , 9.0m   ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Guaraná Fantástica"                , 4.5m   ));
                    this.productList.Add(new KeyValuePair<string,decimal>("NuNuCa Nuß-Nougat-Creme"        , 14.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Gumbär Gummibärchen"               , 31.23m ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Schoggi Schokolade"              , 43.9m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Rössle Sauerkraut"                , 45.6m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Thüringer Rostbratwurst"          , 123.79m));
                    this.productList.Add(new KeyValuePair<string,decimal>("Nord-Ost Matjeshering"           , 25.89m ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Gorgonzola Telino"               , 12.5m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Mascarpone Fabioli"              , 32.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Geitost"                         , 2.5m   ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Sasquatch Ale"                   , 14.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Steeleye Stout"                  , 18.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Inlagd Sill"                     , 19.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Gravad lax"                      , 26.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Côte de Blaye"                    , 263.5m ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Chartreuse verte"                , 18.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Boston Crab Meat"                , 18.4m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Jack's New England Clam Chowder" , 9.65m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Singaporean Hokkien Fried Mee"   , 14.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Ipoh Coffee"                     , 46.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Gula Malacca"                    , 19.45m ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Røgede sild"                    , 9.5m   ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Spegesild"                       , 12.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Zaanse koeken"                   , 9.5m   ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Chocolade"                       , 12.75m ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Maxilaku"                        , 20.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Valkoinen suklaa"                , 16.25m ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Manjimup Dried Apples"           , 53.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Filo Mix"                        , 7.0m   ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Perth Pasties"                   , 32.8m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Tourtière"                        , 7.45m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Pâté chinois"                      , 24.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Gnocchi di nonna Alice"          , 38.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Ravioli Angelo"                  , 19.5m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Escargots de Bourgogne"          , 13.25m ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Raclette Courdavault"            , 55.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Camembert Pierrot"               , 34.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Sirop d'érable"                   , 28.5m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Tarte au sucre"                  , 49.3m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Vegie-spread"                    , 43.9m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Wimmers gute Semmelknödel"        , 33.25m ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Louisiana Fiery Hot Pepper Sauce", 21.05m ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Louisiana Hot Spiced Okra"       , 17.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Laughing Lumberjack Lager"       , 14.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Scottish Longbreads"             , 12.5m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Gudbrandsdalsost"                , 36.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Outback Lager"                   , 15.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Fløtemysost"                    , 21.5m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Mozzarella di Giovanni"          , 34.8m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Röd Kaviar"                       , 15.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Longlife Tofu"                   , 10.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Rhönbräu Klosterbier"              , 7.75m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Lakkalikööri"                      , 18.0m  ));
                    this.productList.Add(new KeyValuePair<string,decimal>("Original Frankfurter grüne Soße" , 13.0m  ));
                }

                return this.productList;
            }
        }

        #endregion
    }
}

 

728x90

 

▶ OrderData.cs

using System;

namespace HowToParallelizeDataIntensiveOperationsOnInMemoryData
{
    /// <summary>
    /// 주문 데이터
    /// </summary>
    public class OrderData
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 주문 ID - OrderID

        /// <summary>
        /// 주문 ID
        /// </summary>
        public int OrderID { get; set; }

        #endregion

        #region 고객명 - CustomerName

        /// <summary>
        /// 고객명
        /// </summary>
        public string CustomerName { get; set; }

        #endregion

        #region 주문일 - OrderDate

        /// <summary>
        /// 주문일
        /// </summary>
        public DateTime OrderDate { get; set; }

        #endregion

        #region 제품명 - ProductName

        /// <summary>
        /// 제품명
        /// </summary>
        public string ProductName { get; set; }

        #endregion

        #region 가격 - Price

        /// <summary>
        /// 가격
        /// </summary>
        public decimal Price { get; set; }

        #endregion

        #region 수량 - Quantity

        /// <summary>
        /// 수량
        /// </summary>
        public int Quantity { get; set; }

        #endregion
    }
}

 

300x250

 

▶ OrderDataListSource.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;

namespace HowToParallelizeDataIntensiveOperationsOnInMemoryData
{
    /// <summary>
    /// 주문 데이터 리스트 소스
    /// </summary>
    public class OrderDataListSource : IListSource
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 잠금자
        /// </summary>
        private static object locker = new object();

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 주문 데이터 리스트
        /// </summary>
        private List<OrderData> orderDataList;

        /// <summary>
        /// 카운트
        /// </summary>
        private int count = 0;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 리스트 컬렉션 포함 여부 - ContainsListCollection

        /// <summary>
        /// 리스트 컬렉션 포함 여부
        /// </summary>
        public bool ContainsListCollection
        {
            get
            {
                return false;
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - OrderDataListSource(count)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="count">카운트</param>
        public OrderDataListSource(int count)
        {
            this.count = count;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 리스트 구하기 - GetList()

        /// <summary>
        /// 리스트 구하기
        /// </summary>
        /// <returns>리스트</returns>
        public IList GetList()
        {
            if(this.orderDataList == null)
            {
                lock(this.locker)
                {
                    if(this.orderDataList == null)
                    {
                        GenerateOrderData();
                    }
                }
            }

            return this.orderDataList;
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 주문 데이터 생성하기 - GenerateOrderData()

        /// <summary>
        /// 주문 데이터 생성하기
        /// </summary>
        private void GenerateOrderData()
        {
            this.orderDataList = new List<OrderData>(this.count);

            Random random = new Random();

            int customerCount = Data.CustomerList.Count;
            int productCount  = Data.ProductList.Count;

            for(int i = 0; i < this.count; i++)
            {
                OrderData orderData = new OrderData();

                orderData.OrderID      = i + 1;
                orderData.CustomerName = Data.CustomerList[pRandom.Next(customerCount)];
                orderData.OrderDate    = DateTime.Today.Subtract(TimeSpan.FromDays(random.Next(180)));

                KeyValuePair<string, decimal> productKeyValuePair = Data.ProductList[random.Next(productCount)];

                orderData.ProductName = productKeyValuePair.Key;
                orderData.Price       = productKeyValuePair.Value;
                orderData.Quantity    = random.Next(200) + 1;

                this.orderDataList.Add(orderData);
            }
        }

        #endregion
    }
}

 

▶ ViewModel.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;

namespace HowToParallelizeDataIntensiveOperationsOnInMemoryData
{
    /// <summary>
    /// 뷰 모델
    /// </summary>
    public class ViewModel : INotifyPropertyChanged
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Event
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 속성 변경시 - PropertyChanged

        /// <summary>
        /// 속성 변경시
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 주문 데이터 리스트 소스
        /// </summary>
        private OrderDataListSource orderDataListSource;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 주문 데이터 리스트 소스 - OrderDataListSource

        /// <summary>
        /// 주문 데이터 리스트 소스
        /// </summary>
        public OrderDataListSource OrderDataListSource
        {
            get
            {
                return this.orderDataListSource;
            }
            set
            {
                if(this.orderDataListSource == value)
                {
                    return;
                }

                this.orderDataListSource = value;

                OnPropertyChanged("ListSource");
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - ViewModel()

        /// <summary>
        /// 생성자
        /// </summary>
        public ViewModel()
        {
            OrderDataListSource = new OrderDataListSource(1000000);
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

        #region 속성 변경시 처리하기 - OnPropertyChanged(propertyName)

        /// <summary>
        /// 속성 변경시 처리하기
        /// </summary>
        /// <param name="propertyName">속성명</param>
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if(PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion
    }
}

 

▶ MainWindow.xaml

<Window
    x:Class="HowToParallelizeDataIntensiveOperationsOnInMemoryData.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
    xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
    xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
    xmlns:local="clr-namespace:HowToParallelizeDataIntensiveOperationsOnInMemoryData"
    Width="800"
    Height="600"
    Title="MainWindow">
    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <Grid>
        <dx:PLinqInstantFeedbackDataSource x:Name="pLinqInstantFeedbackDataSource"
            ListSource="{Binding Path=OrderDataListSource}" />
        <dxg:GridControl x:Name="gridControl"
            ItemsSource="{Binding ElementName=pLinqInstantFeedbackDataSource, Path=Data}">
            <dxg:GridControl.Columns>
                <dxg:GridColumn x:Name="idGridColumn"
                    FieldName="OrderID"
                    Header="ID"
                    Width="60"
                    MinWidth="60"
                    AllowColumnFiltering="False"
                    AllowGrouping="False" />
                <dxg:GridColumn x:Name="customerNameGridColumn"
                    FieldName="CustomerName"
                    Width="200" />
                <dxg:GridColumn x:Name="orderDateGridColumn"
                    FieldName="OrderDate"
                    Width="100"
                    AllowColumnFiltering="False">
                    <dxg:GridColumn.EditSettings>
                        <dxe:DateEditSettings DisplayFormat="d" />
                    </dxg:GridColumn.EditSettings>
                </dxg:GridColumn>
                <dxg:GridColumn x:Name="productNameGridColumn"
                    FieldName="ProductName"
                    Width="200" />
                <dxg:GridColumn x:Name="priceGridColumn"
                    FieldName="Price"
                    Width="60" />
                <dxg:GridColumn x:Name="quantityGridColumn"
                    FieldName="Quantity"
                    Width="60" />
            </dxg:GridControl.Columns>
            <dxg:GridControl.View>
                <dxg:TableView
                    AutoWidth="False"
                    ShowTotalSummary="False"
                    RowAnimationKind="Opacity" />
            </dxg:GridControl.View>
        </dxg:GridControl>
    </Grid>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Closed">
            <i:InvokeCommandAction Command="{Binding ElementName=pLinqInstantFeedbackDataSource, Path=DisposeCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Window>

 

728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요