Windows 10 UWP Uygulamalarının Hafıza Kullanım Durumu için MemoryManager sınıfını kullanmak

Windows 10 UWP uygulaması geliştirirken hafıza‘nın ne kadarını kullandığınızı ve kullanabileceğiniz ne kadar hafıza alanı kaldığını bulmanız gerekebilir.

Bu durumda Windows.System namespace‘i altında yeralan MemoryManager sınıfını kullanabiliriz.

Hemen Visual Studio açarak yeni bir proje oluşturalım;

Öncelikle MainPage.xaml dosyasını açalım ve içerisine aşağıdaki kodları yazarak ekranımızı tasarlayalım;

<Page x:Class=”MemoryManagerOrnek.MainPage” xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” xmlns:local=”using:MemoryManagerOrnek”>

&lt;StackPanel&gt;

    &lt;TextBlock Text="AppMemoryUsage:" /&gt;
    &lt;TextBlock Name="AppMemoryUsage" /&gt;
    &lt;TextBlock Text="AppMemoryUsageLimit:" /&gt;
    &lt;TextBlock Name="AppMemoryUsageLimit" /&gt;

&lt;/StackPanel&gt;

</Page></pre>

Şimdi MainPage.xaml.cs dosyasını açalım ve DispatcherTimer sınıfından yeni bir değişken tanımlayıp, MainPage sınıfının constructor‘ında, her 1 saniyede bir tetiklenmesini sağlayalım;

DispatcherTimer timer = null;

public MainPage()
{
    this.InitializeComponent();

    timer = new DispatcherTimer();
    timer.Interval = new TimeSpan(0, 0, 1);
    timer.Tick += timer_Tick;
    timer.Start();
}

Artık timer_Tick() metodumuzu yazabiliriz;

private void timer_Tick(object sender, object e)
{
    AppMemoryUsage.Text = string.Format("{0} ({1:0.00} MB)", MemoryManager.AppMemoryUsage, MemoryManager.AppMemoryUsage / (1024.0 * 1024.0));
    AppMemoryUsageLimit.Text = string.Format("{0} ({1:0.00} GB)", MemoryManager.AppMemoryUsageLimit, MemoryManager.AppMemoryUsageLimit / (1024 * 1024 * 1024));
}


Yukarıdaki metodun içerisinde öncelikle MemoryManager sınıfının AppMemorryUsage **property**'sinin değerini okuduk ve bunu (*1024* x *1024*) değerine bölerek kaç **megabayt** (*MB*) yaptığını hesapladık, *AppMemoryUsage* isimli Textblock nesnesinde gösterdik.

Aynı şekilde MemoryManager sınıfının AppMemorryUsageLimit **property**'sinin değerini okuduk ve bunu (*1024* x *1024* x *1024*) değerine bölerek kaç **gigabayt** (*GB*) yaptığını hesapladık, *AppMemoryUsageLimit* isimli Textblock nesnesinde gösterdik.

Uygulama açıldıktan sonra her 1 saniyede bir, uygulamanın o anda *kullandığı* **hafıza miktarı** ve *kullanabileceği* **hafıza miktarı** ekranda gösterilecek.

![](/assets/uploads/2016/02/MemoryManagerOrnek-2.png)

*Not : Eğer uygulamayı bilgisayarınızda çalıştıracak olursanız, **AppMemoryUsageLimit** değeri olarak, sistemde kullanılabilir boş hafıza miktarını görmelisiniz. Eğer **512 MB** hafızaya sahip bir cep telefonunda çalıştıracak olursanız, **185 MB** limitini, **1024 MB** (1 GB) hafızalı bir cep telefonunda çalıştıracak olursanız **390 MB** limit görmelisiniz.*

AspNet Core 1.0 MVC6 projesine InMemory Caching desteği eklemek

Bu makaleyi okumadan önce Asp.Net Kategorisindeki diğer makalelerimi okumanızı tavsiye ederim.

Caching (önbellekleme) sayesinde elde etmesi uzun sürecek verilere çok daha hızlı bir şekilde ulaşabiliriz.

Hemen yeni bir Asp.Net Core 1.0 MVC 6 projesi oluşturalım ve InMemory Caching ekleyelim.

Öncelikle örnek projeyi oluşturmak istediğimiz dizine Command Prompt (Windows) veya Terminal (MacOS, Linux) içerisinden gidiyoruz ve aşağıdaki kodları çalıştırıyoruz;

yo aspnet // Empty Application seçeneğini seçiyoruz // Projeye inmemorycaching ismini veriyoruz

cd inmemorycaching code .</pre>

Visual Studio Code açıldıktan sonra project.json dosyasını açıyor ve içindeki dependencies kısmına aşağıdaki satırı ekliyoruz;

"Microsoft.AspNet.Mvc": "6.0.0-rc1-final"

Böylece Empty Application tipindeki AspNet Core uygulamamıza MVC 6 paketini kullanacağımızı söylemiş olduk. Fakat paket henüz projemizin olduğu dizine indirilmedi. Bunun için Command Prompt (Windows) veya Terminal (MacOS, Linux) içerisinde aşağıdaki kodu çalıştırıyoruz;

dnu restore

Artık Startup.cs dosyasını açabilir ve projemizde Mvc kullanmaya başlayabiliriz. Öncelikle ConfigureServices() methodu içerisinde uygulamamıza Mvc‘yi tanıtıyoruz;

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
}

Bu noktada Configure() methodu içerisinde Mvc‘yi kullanabilir, yapılandırabiliriz;

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}"
    );
});

AspNet Core 1.0 üzerinde geliştirdiğimiz projemizde artık MVC 6 yapılandırıldı.

İlk action methodumuzu yazmak için projenin olduğu dizinde Controllers dizini oluşturalım. Bunun için aşağıdaki komutları Command Prompt (Windows) veya Terminal (MacOS, Linux) içerisinde çalıştırabiliriz;

mkdir Controllers

Visual Studio Code editörüne dönerek Controllers dizininde HomeController.cs dosyasını oluşturuyoruz ve içerisine Index() methodunu aşağıdaki gibi yazıyoruz;

using Microsoft.AspNet.Mvc;

namespace inmemorycaching.Controllers
{
    public class HomeController : Controller
    {
        public string Index()
        {
            return "";
        }
    }
}

Bu noktaya kadar http://localhost:5000 adresine girdiğimizde boş bir sayfa ile karşılaşacağımız uygulamayı hazırladık.

project.json dosyasını açalım ve dependencies kısmına aşağıdaki paketi ekleyelim;

"Microsoft.Extensions.Caching.Memory": "1.0.0-rc1-final"

Command Prompt (Windows) veya Terminal (MacOS, Linux) içerisinde aşağıdaki kodu çalıştıralım;

dnu restore

Artık projemizde caching (önbellekleme) yapabiliriz. Öncelikle Startup.cs dosyasını tekrar açalım ve ConfigureServices() methodunun içini aşağıdaki gibi değiştirelim;

services.AddCaching().AddMvc();

Şimdi HomeController.cs dosyasını açıp aşağıdaki şekilde güncelleyebiliriz;

public class HomeController : Controller
{
    private IMemoryCache cache;

    public HomeController(IMemoryCache _cache)
    {
        cache = _cache;
    }

    public string Index()
    {
        var start = DateTime.Now;

        IEnumerable<int> rakamlar;

        if(!cache.TryGetValue("Rakamlar", out rakamlar))
        {
            rakamlar = Enumerable.Range(1, 10000);

            cache.Set("Rakamlar", rakamlar);
        }

        return $"10.000 öğeli listenin elde edilme süresi : {(DateTime.Now - start).TotalMilliseconds} ms.";
    }
}

Öncelikle HomeController sınıfı içinde IMemoryCache tipinde cache değişkenini tanımladık.

using kısmına Microsoft.Extensions.Caching.Memory namespace’ini eklemeyi unutmamalıyız.

HomeController sınıfının constructor‘ında IMemoryCache tipinde bir parametre aldık ve cache değişkeninde sakladık.

Index() action methodunda içerisinde 10.000 adet rakam saklayacağımız değişkenimizi tanımlıyoruz.

cache değişkeninin TryGetValue() methodu aracılığı ile liste değişkenini cache‘teki liste ile doldurmaya çalışıyoruz.

Eğer dolduramazsak, cache‘e 10.000 rakamlı değişkeni ekliyoruz.

Index() action method’unun başında ve sonunda aldığımız iki zaman değişkeni aracılığı ile arada geçen zamanı hesaplıyoruz ve ekranda gösteriyoruz.

http://localhost:5000 adresine ilk ziyaretimizde 10.000 elemanlı diziye yaklaşık 6 saniye içerisinde ulaşabildiğimizi görüyoruz.

Takip eden ziyaretlerimizde ise 0 milisaniye içerisinde aynı diziye ulaşabiliyoruz;

IMemoryCache interface‘inde tanımlı olan Set() methodu ile cache‘e eklediğimiz nesnenin belli bir süre sonra otomatik olarak cache‘ten silinmesini istiyorsak, MemoryCacheEntryOptions sınıfından yeni bir instance çıkartıp, SetAbsoluteExpiration() methoduna istediğimiz süreyi TimeSpan tipinde vermeliyiz;

cache.Set("Rakamlar", rakamlar, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(30)));


MSP Webinar Serisi, Universal Windows Platform - Azure Backend, Şubat 2016

04 Şubat 2016 tarihinde, Microsoft MSP öğrencilere özel Universal Windows Platform - Azure Backend webinar‘i gerçekleştirdim.

Bu etkinliğin videosunu Youtube (UWP Azure Backend Webinar) üzerinden veya Channel 9 (MSP Webinar 2016 UWP Azure Backend) üzerinden izleyebilirsiniz.

SASS (scss dosyaları) ile diziler ve döngüler

Bu makaleyi okumadan önce Asp.Net Kategorisindeki diğer makalelerimi ve SASS (scss dosyaları) nedir? makalesini okumanızı tavsiye ederim.

SASS dosyalarında birden fazla değişkenin bir dizi olarak ele alınmasını ve bu dizideki her eleman için bir css stili oluşmasını isteyebiliriz.

Örneğin SASS dosyamızda aşağıdaki değişkenleri tanımlamış olalım;

$Twitter: #41b7d8;
$Facebook: #3b5997;
$GooglePlus: #d64937;
$Linkedin: #0073b2;

SASS dosyalarında liste tipinde bir değişken tanımı yapmak için, değişkene değerleri virgüllerle ayırarak (comma-seperated) vermemiz lazım. Örneğin;

$SocialColors: $Twitter, $Facebook, $GooglePlus, $Linkedin;

Artık @for döngüsü yazarak $SocialColors dizisinin her bir elemanına erişebiliriz;

@for $i from 1 through length($SocialColours) {
    img-#{$i} {
        background: nth($SocialColors, $i);
    }
}

@for döngüsü ile döndüğümüz değişkenin kaçıncı elemanında olduğumuzu #{$i} kodu ile alabiliyoruz, herhangi bir dizinin istediğimiz sıradaki elemanını nth(dizi-adi, sira) kod parçası ile alabiliyoruz.

Yukarıdaki SASS kodunun css çıktısı aşağıdaki gibi olacaktır;

img-1 {
    background:#41b7d8
}
img-2 {
    background:#3b5997
}
img-3 {
    background:#d64937
}
img-4 {
    background:#0073b2
}

Peki, img-1, img-2, img-3 isimli stiller değil de, twitter, facebook, linkedin, isimli stiller oluşturmak isteseydik?

SASS dosyalarında Array (dizi) yerine, Dictionary (sözlük) tipinde değişkenler de oluşturabiliriz. Böylece her eleman iki parçadan oluşacak, örneğin biri değişkenin adını, diğeri rengini içerebilir;

$Social:
    (Twitter, $Twitter),
    (Facebook, $Facebook),
    (GooglePlus, $GooglePlus),
    (Linkedin, $Linkedin);

@each döngüsü ile $Social değişkeninin her elemanına ulaşabilir, ulaştığımız elemanın ilk parçasına $name değişkeni, ikinci parçasına $color değişkeni aracılığıyla ulaşabiliriz;

@each $name, $color in $Social {
    .social-link-#{$name} {
        background-color: $color;
        color: darken($color, 35%);
    }
}

Değişkenin adını, css çıktısına eklemek için #{} kod parçasını kullandık.

Yukarıdaki SASS kodunun css çıktısı aşağıdaki gibi olacaktır;

.social-link-Twitter {
    background-color:#41b7d8;
    color:#114655;
}
.social-link-Facebook {
    background-color:#3b5997;
    color:#090d17;
}
.social-link-GooglePlus {
    background-color:#d64937;
    color:#4b160f;
}
.social-link-Linkedin {
    background-color:#0073b2;
    color:#000;
}

darken() methodunu da kullanarak yazı renginin arkaplan renginden 35% daha koyu olmasını sağladık. Hatta background-image stiline dizi elemanının isminden değer vermek için aşağıdaki kodu kullanabiliriz;

background-image: url('/images/#{$name}.png');

Kaynak : SASSMeister

EntityFramework Expression kullanarak esnek veritabanı sorguları

Veritabanında gerçekleşecek sorguları yazdığımız Veritabanı Erişim Katmanı‘nda (Data Access Layer, DAL) genelde bir tablodaki kayıtları liste olarak veya aranılan kritere göre filtreleyerek döndüren methodlarımız olur.

Projenin geliştirilme süresince gelişen ihtiyaçlara göre bu methodlara çeşitli kriterlere göre filtreleme yapan yeni methodlar eklenir ve bir süre sonra işin içinden çıkılmaz bir hale gelebilir.

Expression‘ları kullanarak bu methodları azaltabiliriz.

Hemen Visual Studio‘yu açalım ve yeni bir Console Application projesi oluşturalım;

Projeye Nuget Package Manager‘ı kullanarak EntityFramework paketini ekleyelim;

Projeye TestDatabaseDataContext isminde yeni bir class ekleyelim ve içerisine aşağıdaki property tanımlamasını ekleyelim;

public class TestDatabaseDataContext : DbContext { public DbSet<Country> Countries { get; set; } }</pre>

Projeye Country isminde yeni bir class daha ekleyelim ve içerisine aşağıdaki property tanımlamalarını yapalım;

public class Country
{
    public int Id { get; set; }

    public string Name { get; set; }

    public decimal Area { get; set; }
}

Tekrar Program.cs dosyasını açalım ve içerisinde aşağıdaki iki method’u yazalım;

public static IEnumerable<Country> GetCountryList()
{
    using (var context = new TestDatabaseDataContext())
    {
        var ulkeler = (from country in context.Countries select country);

        foreach (var item in ulkeler)
        {
            yield return item;
        }
    }
}

public static Country GetCountry(int id)
{
    using (var context = new TestDatabaseDataContext())
    {
        return (from country in context.Countries select country).FirstOrDefault(e => e.Id == id);
    }
}

Böylece ülkelerin listesini ve aldığı id parametresine göre tek bir ülke’yi geri döndüren iki method‘umuz olacak. Fakat zamanla gelişen yeni talepler ile bu method’lara, isme göre ülke listesini döndüren method, belli bir yüzölçümünden büyük ülkelerin listesini döndüren method, vs eklenecektir.

Expression sınıfını kullanarak bu methodları tekilleştirebiliriz. Hemen aşağıdaki method’u ekleyelim;

public static IEnumerable<Country> GetCountryList(Expression<Func<Country, bool>> expression)
{
    using (var context = new TestDatabaseDataContext())
    {
        var ulkeler = (from country in context.Countries select country).Where(expression);

        foreach (var item in ulkeler)
        {
            yield return item;
        }
    }
}

İstediğimiz yerde artık bu methodu aşağıdaki şekillerde kullanabiliriz;

var ulkeler1 = GetCountryList(u => u.Name.Contains("rika"));
// Amerika, Afrika, Kosta Rika, ...

var ulkeler2 = GetCountryList(u => u.Area > 100);

var ulkeler3 = GetCountryList(u => u.Id < 10);


*Böylece tek bir method'a nasıl bir sonuç listesi istediğimizi tarif ediyoruz ve o bize o sonucu döndürüyor.*

Engin Polat hakkında

Senior Software Engineer, @Microsoft

Ada ve Ege'nin babası ;)

Kategoriler

İstatistik

Makale Adedi: 484

Creative Commons Lisansı