Tag Archives: ForEach

Workflow Foundation ile Kopyalanarak Çoğaltılan Aktiviteler

Bir önceki yazımızda sırasıyla geçiş yaptığımız argümanlara göre toplam maliyeti hesaplayan bir workflow oluşturmuştuk. Şimdiye kadar sadece taşıma ücretini hesaplamıştık. Şimdi bu yazımızda her bir ürünün lojik olarak maliyetlerini ekleyeceğiz.

Bu yüzden bir önceki yazımızda oluşturduğumuz Siparisİslemi projeminiz üzerinde çalışacağız. Visual Studio’yu başlatıp yeni bir proje oluşturalım. Other Project Types –> Visual Studio Solutions seçeneği ile Kopyalanarak Çoğaltılan Aktiviteler adında yeni bir boş solution oluşturalım. Şimdi de C:\Users\Soner\Documents\Visual Studio 2010\Projects\Siparisİslemi altındaki Siparisİslemi klasörünü az önce oluşturduğumuz Kopyalanarak Çoğaltılan Aktiviteler klasörünün içine kopyalayalım.

WF-Folder

Solution Explorer kısmından Add->Existing Project diyerek Kopyalanarak Çoğaltılan Aktiviteler/Siparisİslem klasörünün içinde bulunan Siparisİslemi.csproj dosyamızı ekleyelim.

SiparişÜrün İşlemini Ekleyelim

ForEach aktivitesi Collection kısmındaki her bir madde için bir aktivite çalıştırır. Bu proje için bizim tam da istediğimiz budur aslında.

SiparisWF.xaml dosyamızı dizayn modunda açalım.  “İlk Toplam” aktivitemizin altına bir adet ForEach<T> aktivitesi sürükleyip bırakalım. DisplayName özelliğini Sipariş Ürünlerini Biriktirme olarak adlandıralım. Expression özelliğine SiparisBilgisi.Ogeler yazalım. Fakat bunu yazdığımızda bir hata alırız. Aktivitenin <T> olarak tanımlanması bu aktivitenin generic sınıf olduğunu, bu yüzden tip olarak collection içeren bir tip tanımlamamız gerektiğini bize gösterir. Varsayılan tip olarak Int32 seçildiğinden SiparisBilgisi.Ogeler ifadesi de bir Int32 tipinde collection içermediğinden bu hatayı alırız. Bu yüzden ArgumentType seçeneğini Browse Type diyerek Siparisİslemi.SiparisOge olarak belirtmeliyiz.

WF-BrowseType2

Bu tipi seçtiğimizde artık SiparisBilgisi.Ogeler değeri Siparisİslemi.SiparisOge tipinde bir collection içerir. (Siparis.cs içerisinde yazdığımız kod nedeniyle) Hata ortadan kalkmış olur. Şimdi ForEach<T> aktivitesi içerisine bir Assign aktivitesi sürükleyip bırakalım.

NOT: Foreach<T> aktivitesi içerisine sadece bir basit aktivite sürükleyebiliriz. Eğer birden fazla aktiviteye ihtiyacınız olursa, içerisine bir Sequence aktivitesi sürükleyip diğer aktiviteleri bunun içerisine yerleştirebilirsiniz.

Assign aktivitemizin To özelliğini ToplamMaliyet, Value özelliğini de ToplamMaliyet + (item.Miktar * 10.0D) olarak atayalım. Bu işlem sipariş içerisindeki her miktar için toplam maliyete 10 ekler.

Şimdi “Sipariş Ürünlerini Biriktirme” aktivitesinin altına bir Writeline aktivitesi ekleyelim. DisplayName özelliğine “Toplam Maliyeti Göster”, Text özelliğine de “Ürün Toplamı: ” + ToplamMaliyet.ToString() ifadesini atayalım. Bu sipariş edilmiş ürünlerin toplamını, taşıma ücretini eklemeden önce gösterir.

Sipariş Ürünlerini Ekleme

Şimdi bu özelliği test etmeden önce Sipariş sınıfı içerisindeki SiparisOge nesnelerini düzenlememiz lazım. Program.cs dosyamızı açalım ve aşağıdaki kodumuzu siparisim nesnesini oluşturduktan hemen sonra yazmaya başlayalım.


siparisim.Ogeler.Add(new SiparisOge
{
SiparisOgeID = 1,
Miktar = 1,
OgeID = "12345",
Tanım = "Alet"
});

siparisim.Ogeler.Add(new SiparisOge
{
SiparisOgeID = 2,
Miktar = 3,
OgeID = "12346",
Tanım = "Küçük Alet"
});

siparisim.Ogeler.Add(new SiparisOge
{
SiparisOgeID = 3,
Miktar = 2,
OgeID = "12347",
Tanım = "Süper Alet"
});

Şimdi F5 ile projemizi çalıştıralım.

Sipariş Alındı
Ürün Toplamı: 60
Toplam Maliyet: 120,0
Workflow’un döndürdüğü Toplam Maliyet 120,0
Enter to Exit

Peki bu nasıl hesaplandı?

SiparisOge sınıfının miktar olarak sırasıyla 1, 3, 2 ogeler mevcut. Bunların toplamı 6 yapıyor. Her biri için 10 eklediğimizi hatırlayalım. Bu da toplamı 60 yapar. Bir önceki yazıda gördüğümüz üzere Taşıma Ücreti’de 60 olarak hesaplamıştık. Bu ikisinin toplamı da sonuçta gördüğümüz gibi 120 değerini elde ediyoruz.

Tüm Program.cs kodumuz aşağıdaki şekildedir;


using System;
 using System.Linq;
 using System.Activities;
 using System.Activities.Statements;
 using System.Collections.Generic;

namespace Siparisİslemi
 {

class Program
 {
 static void Main(string[] args)
 {
 Siparis siparisim = new Siparis
 {
 SiparisID = 1,
 Tanım = "Sipariş Tanımı",
 SiparisMetodu = "İkiSonrakiGün",
 ToplamAgirlik = 100,
 };

siparisim.Ogeler.Add(new SiparisOge
 {
 SiparisOgeID = 1,
 Miktar = 1,
 OgeID = "12345",
 Tanım = "Alet"
 });

siparisim.Ogeler.Add(new SiparisOge
 {
 SiparisOgeID = 2,
 Miktar = 3,
 OgeID = "12346",
 Tanım = "Küçük Alet"
 });

siparisim.Ogeler.Add(new SiparisOge
 {
 SiparisOgeID = 3,
 Miktar = 2,
 OgeID = "12347",
 Tanım = "Süper Alet"
 });

//Workflow için input argümanlarını oluşturalım
 IDictionary<string, object> input = new Dictionary<string, object>
 {
 {"SiparisBilgisi", siparisim}
 };

//Workflow'u çalıştıralım
 IDictionary<string, object> output = WorkflowInvoker.Invoke(new SiparisWF(), input);

//Workflow'dan geri dönen ToplamMaliyet'i alalım
 decimal toplam = (decimal)output["ToplamMaliyet"];
 Console.WriteLine("Workflow'un döndürdüğü Toplam Maliyet {0}", toplam);
 Console.WriteLine("Enter to Exit");
 Console.ReadLine();
 }
 }
 }

ParallelForEach Aktivitesi

ForEach aktivitesi yerine ParallelForEach aktiviteisi de kullanabilirdik. İki aktivite de aynı şekilde yapılandırılmıştır. Tek fark aktivitelerin nasıl çalıştırıldığıdır.

ParallelForEach’in adından da anlaşılacağı gibi alt aktiviteler eşzamanlı olarak çalışırlar. ForEach aktivitesinde ise alt aktiviteler sıralı olarak çalışırlar.