Arşiv

Etiketlenen yazılar msdn

Windows 8 Metro Style Uygulamalarda Async Desteği

17 Kasım 2011 Yorum yapılmamış

Windows 8 Programlama makale serisine, Async Desteği ile devam ediyoruz.

Asenkron programlama ölçeklendirilebilir ve yanıt veren (donmayan) uygulama geliştirmek için uzun yıllardır bilinen bir teknik. Uzun yıllardır bilinmesine rağmen, uygulama geliştiriciler olarak asenkron programlama bize hep zor gelmiştir.

.Net 4.5 ile birlikte asenkron programlama Async Framework sayesinde kolay programlanabilir hale getirildi ve Task Parallel Library‘nin (TPL) içerisine entegre edildi.

Asenkron programlama ile ilgili daha detaylı bilgiye, MSDN‘in Visual Studio Asynchronous Programming sayfasından ulaşabilirsiniz.

Bu makalede basit bir örnek ile async ve await anahtar kelimelerinin kullanımını inceleyeceğiz.

Yapacağımız örnek bir web sitesinin içeriğini okuyacak ve web adreslerini toplayacak. İlk olarak standart programlama yöntemlerini kullanarak uygulamamızı geliştireceğiz, daha sonra async ve await anahtar kelimeleri ile asenkron programlama öğelerini uygulamamıza dahil edeceğiz.

Hemen yeni bir Visual Studio 2011 açarak geliştirmeye başlayalım;

Yeni Proje oluşturma dialog kutusunda Windows Metro Style grubunda yer alan Application proje şablonunu seçelim ve projemize bir isim verelim (bu örnekte benim kullandığım isim, AsyncOrnek)

Proje oluşturulduğunda MainPage.xaml dosyasının içeriği;

<UserControl x:Class="Windows8ApplicationBar.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d"
	d:DesignHeight="768" d:DesignWidth="1366">

	<Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
	</Grid>

</UserControl>

İlk önce uygulamamıza bir TextBox, bir Button ve bir ListBox nesnesi ekliyoruz;

<Grid x:Name="LayoutRoot" Background="#FF0C0C0C">

	<TextBox x:Name="txtKaynakHtml" Width="600" Height="700" HorizontalAlignment="Left" />
	<ListBox x:Name="lbUrlList" Width="600" Height="700" HorizontalAlignment="Right" />
	<Button x:Name="btnTara" Content="Tara" HorizontalAlignment="Center" />

</Grid>

Böylece uygulama ekranımız şu şekilde gözüküyor;

TextBox kontrolünün Text özelliğine web sitesinin kaynak html’ini atayacağımız için, çok satır gösterebilir olması lazım (MultiLine)

WPF TextBox kontrolünün MultiLine olabilmesi için, TextBox element’ine şu özellikleri ekliyoruz;

TextWrapping="Wrap" AcceptsReturn="True" ScrollViewer.VerticalScrollBarVisibility="Visible"

Button kontrolüne basıldığında tarama işlemini başlatmak için, Button element’inde Click olayını yakalıyoruz;

Click="btnTara_Click"

Böylece uygulamamızın XAML kod’u aşağıdaki hale gelmiş oluyor;

<UserControl x:Class="AsyncOrnek.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d"
	d:DesignHeight="768" d:DesignWidth="1366">

	<Grid x:Name="LayoutRoot" Background="#FF0C0C0C">

		<TextBox x:Name="txtKaynakHtml" Width="600" Height="700" HorizontalAlignment="Left" TextWrapping="Wrap" AcceptsReturn="True" ScrollViewer.VerticalScrollBarVisibility="Visible" />
		<ListBox x:Name="lbUrlList" Width="600" Height="700" HorizontalAlignment="Right" />
		<Button x:Name="btnTara" Content="Tara" HorizontalAlignment="Center" Click="btnTara_Click" />

	</Grid>

</UserControl>

MainPage.xaml.cs dosyasında btnTara_Click method’unu yazıyoruz;

private void btnTara_Click(object sender, RoutedEventArgs e)
{
}

Öncelikle, taradığımız sitede bulacağımız url’leri saklayacağımız string dizisini oluşturalım;

List<string> UrlList = new List<string>();

HttpClient sınıfından yeni bir instance oluşturup, Get() method’una, tarayacağımız sitenin adresini yazalım.

Get() method’undan dönen HttpResponseMessage tipindeki cevabı bir değişkene atayalım;

var HttpCagri = new HttpClient().Get("http://www.enginpolat.com");

HttpClient sınıfı System.Net.Http namespace‘inde yer aldığı için, MainPage.xaml.cs dosyasının using kısmına

using System.Net.Http;

satırını ekleyelim.

HttpCagri değişkeninin sitenin kaynak html’ini okuyabildiğinden emin olmak için, EnsureSuccessStatusCode() method’unu çağıralım.

Böylece HttpContent tipindeki Content özelliğine erişebilir olacağız. Content özelliğinin ReadAsString() method’u kaynak html’ini döndürecek, biz de bir değişken aracılığıyla bu html’i saklayacağız.

var KaynakHtml = HttpCagri.EnsureSuccessStatusCode().Content.ReadAsString();

Elimizdeki bu html verisini, arayüzdeki txtKaynakHtml TextBox‘ında göstermek için;

txtKaynakHtml.Text = KaynakHtml;

Şimdi yapmamız gereken, KaynakHtml değişkenindeki url‘leri bulmak. Bunun için Regex sınıfından faydalanacağız ve yazacağımız Regular Expression‘a uyan url’leri UrlList değişkeninde biriktireceğiz.

Regex sınıfı System.Text.RegularExpressions namespace’inde olduğu için, MainPage.xaml.cs dosyasının using kısmına

using System.Text.RegularExpressions;

satırını ekleyelim.

Öncelikle Regex sınıfının static Matches method’una KaynakHtml değişkenini, Regular Expression metnini ve arama yaparken büyük/küçük harf ayrımı yapmaması için RegexOptions.IgnoreCase değerini parametre olarak veriyoruz.

RegexOptions parametresine verebileceğimiz diğer değerler;

  • RegexOptions.None
  • RegexOptions.IgnoreCase
  • RegexOptions.Multiline
  • RegexOptions.ExplicitCapture
  • RegexOptions.Compiled
  • RegexOptions.Singleline
  • RegexOptions.IgnorePatternWhitespace
  • RegexOptions.RightToLeft
  • RegexOptions.ECMAScript
  • RegexOptions.CultureInvariant

Method’dan dönen MatchCollection tipindeki cevabı bir değişkende saklıyoruz;

var mc = Regex.Matches(KaynakHtml, "href\\s*=\\s*(?:\"(?<1>http://[^\"]*)\")", RegexOptions.IgnoreCase);

Bir foreach döngüsü ile MatchCollection‘daki her Match‘i UrlList‘e ekliyoruz;

foreach (Match m in mc)
{
	UrlList.Add(m.Groups[1].Value);
}

Son olarak arayüzdeki lbUrlList ListBox‘ında bu listeyi gösteriyoruz;

lbUrlList.ItemsSource = UrlList;

İlk çalıştırma aşamasına geldik. Projeyi çalıştırıp Tara butonuna bastığımızda garip bir hata alıyoruz;

Cannot write more bytes to the buffer than the configured maximum buffer size: 65536

Bu hataya, kaynak html’ini aldığımız siteden dönen cevabın 65536 karakterden büyük olması yol açıyor. Çözüm aslında basit;

HttpClient tipindeki değişkenin MaxResponseContentBufferSize özelliğine sitenin kaynak html’inin karakter sayısı kadar büyük bir değer vermemiz lazım.

Bu örnek için ben verilebilecek en büyük değer olan int.MaxValue değerini seçtim, HttpCagri değişkenini tanımladığımız satırı şöyle güncelliyoruz;

var HttpCagri = new HttpClient() { MaxResponseContentBufferSize = int.MaxValue }.Get("http://www.enginpolat.com");

Artık projemizi çalıştırabiliriz;

Buraya kadar uygulamayı çalıştırmaya odaklanmıştık, uygulamayı çalıştırdıktan sonra kullanıyoruz ve farkediyoruz ki, Tara butonuna bastıktan sonra liste dolana kadar uygulama kullanıcıya yanıt vermiyor.

Kullanıcı dostu bir uygulamanın her zaman kullanıcıya yanıt vermesi beklenir. Biz de Tara butonunun yaptığı işi asenkron yapmasını sağlayarak oluşan donmaların önüne geçebiliriz.

Asenkron çalışma yeteneğini eklemek için öncelikle btnTara_Click method’una async anahtar kelimesini ekleyeceğiz;

private async void btnTara_Click(object sender, RoutedEventArgs e)

Uygulamanın donmasına sebep olan en uzun iş, internet sitesinin cevabının alındığı HttpClient sınıfının Get() method’u. Bu yüzden Get() method’unu asenkron özellikte olan GetAsync() method’u ile değiştiriyoruz.

HttpCagri değişkenine değer atamadan önce await anahtar kelimesi ile asenkron yaptığımız çağrının sonuçlanmasını beklemeliyiz. İlgili satırı aşağıdaki şekilde güncelleyelim;

var HttpCagri = await new HttpClient() { MaxResponseContentBufferSize = int.MaxValue }.GetAsync("http://www.enginpolat.com");

Böylece uygulamamıza asenkron çalışabilme yeteneğini kazandırmış olduk. Projenin kodlarının tamamı;

<UserControl x:Class="AsyncOrnek.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d"
	d:DesignHeight="768" d:DesignWidth="1366">

	<Grid x:Name="LayoutRoot" Background="#FF0C0C0C">

		<TextBox x:Name="txtKaynakHtml" Width="600" Height="700" HorizontalAlignment="Left" TextWrapping="Wrap" AcceptsReturn="True" ScrollViewer.VerticalScrollBarVisibility="Visible" />
		<ListBox x:Name="lbUrlList" Width="600" Height="700" HorizontalAlignment="Right" />
		<Button x:Name="btnTara" Content="Tara" HorizontalAlignment="Center" Click="btnTara_Click" />

	</Grid>

</UserControl>
private async void btnTara_Click(object sender, RoutedEventArgs e)
{
	List<string> UrlList = new List<string>();

	var HttpCagri = await new HttpClient() { MaxResponseContentBufferSize = int.MaxValue }.GetAsync("http://www.enginpolat.com");
	var KaynakHtml = HttpCagri.EnsureSuccessStatusCode().Content.ReadAsString();

	txtKaynakHtml.Text = KaynakHtml;

	var mc = Regex.Matches(KaynakHtml, "href\\s*=\\s*(?:\"(?<1>http://[^\"]*)\")", RegexOptions.IgnoreCase);

	foreach (Match m in mc)
	{
		UrlList.Add(m.Groups[1].Value);
	}

	lbUrlList.ItemsSource = UrlList;
}

Windows 8 Programlama Ortamını Hazırlayalım

05 Ekim 2011 Yorum yapılmamış

Windows 8 üzerinde geliştirme yapabilmemiz için öncelikle bilgisayarımıza Windows 8 ve Visual Studio 2011 kurmuş olmamız lazım.

Windows 8 Programlama makalemde kurulumlar ile ilgili bilgi vermiştim.

Eğer MSDN üyeliğiniz varsa, Visual Studio 2011 Ultimate Edition kurmanızı tavsiye ederim.

Kurulum penceresi sade hazırlanmış;

Kurulum tamamlandıktan sonra Visual Studio 2011‘imizi ilk defa çalıştırıyoruz;

Hemen hemen her Visual Studio sürümü ilk çalıştırıldığında bu ekrana benzer bir ekran ile karşılaşırız. Ben Visual C# Development Settings tercihini yaptım, Local Help Documentation seçeneğinden de None seçtim.

Kısa bir yapılandırmanın ardından Visual Studio 2011 Splash Screen ekrana geldi.

Başlangıç ekranımız Visual Studio 2010‘dan farklı değil, Visual Studio 2008‘den beri çok az değişiklik gösterdi.

Help / About Microsoft Visual Studio menüsünden Hakkında penceresini açtığımızda, bilgisayarımıza Visual Studio bileşenlerinin 11. versiyonlarının ve .Net 4.5 versiyonunun kurulu olduğunu görüyoruz.

File / New Project menüsünden yeni bir proje oluşturmak için New Project dialog kutusunu açtığımızda Metro Style proje şablonlarının geldiğini görüyoruz.

Bu ekranda Grid Application ve Split Application seçeneklerinden birini seçebiliriz.

Ofisten küçük bir görüntü; yeni proje şablonunu açtıktan sonra ilk dakikalar;

Windows 8 Programlama başlığını takip ederek özellikle Metro Style uygulama geliştirme konusunda daha ayrıntılı bilgiye sahip olabilirsiniz.

Thread.Sleep ve Thread.SpinWait arasındaki fark

26 Nisan 2011 Yorum yapılmamış

Thread sınıfı ile ilgili en çok karşılaştığım sorulardan birisi; “Thread.Sleep() ile Thread.SpinWait() method’ları arasındaki fark nedir?” olmuştur.

MSDN Process ve Thread dökümanları ne yazık ki bu konuda bize yeterli bilgi sağlamıyor.

Peki Thread sınıfının SpinWait() ve Sleep() method’ları arasındaki fark nedir?

Programming .Net Components kitabının yazarı Juval Löwy‘den alıntı (sayfa 192) yapacağım;

Orjinal : When a thread calls SpinWait(), the calling thread waits the number of iterations specified, and the thread is never added to the queue of waiting threads. As a result, the thread is effectively put to sleep without relinquishing the remainder of its CPU time slot.

The .NET documentation does not define what an iteration is, but it is likely mapped to a predetermined number (probably just one) of NOP (no-operations) assembly instructions. Consequently, the following SpinWait() instruction will take different time to complete on machines with different CPU clock speeds:

const long MILLION = 1000000;
Thread.SpinWait(MILLION);

SpinWait() is not intended to replace Sleep(), but is rather made available as an advanced optimization technique. If you know that some resource your thread is waiting for will become available in the immediate future, it is potentially more efficient to spin and wait, instead of using either Sleep() or a synchronization object, because those force a thread context switch, which is one of the most expensive operations performed by the operating system. Even in the esoteric cases for which SpinWait() was designed, using it is an educated guess at best. SpinWait() will gain you nothing if the resource is not available at the end of the call, or if the operating system preempts your thread because its time slot has elapsed, or because another thread with a higher priority is ready to run. In general, I recommend that you should always use deterministic programming (using synchronization objects in this case) and avoid optimization techniques.

Alıntı’nın önemli cümleleri;

Türkçesi : Eğer bir thread SpinWait() method’unu çağırırsa, parametre ile belirtilen CPU çevrimi boyunca beklemeye geçer ve Bekleyen Threadler (Waiting Threads) listesine kendini eklemez. Böylece, CPU’da bulunduğu slot’tan vazgeçmeden, uyku moduna geçmiş olur.

.NET dokümantasyonuna göre her CPU çevriminde (muhtemelen) bir adet NOP (no-operations) assembly komutu çalıştırır. Fakat, aşağıdaki SpinWait() komutu, farklı hızlarda çalışan CPU’larda farklı sürelerde tamamlanır.

const long MILLION = 1000000;
Thread.SpinWait(MILLION);

SpinWait() method’u, Sleep() method’unun yerine düşünülmemiştir, daha ileri seviye optimizasyon yapılabilmesi için amaçlanmıştır. Eğer çalışan thread’in ihtiyaç duyduğu kaynak, çok kısa süre içerisinde uygun olacaksa (mesela başka bir thread kaynak üzerinde bulunan lock’ı kaldıracaksa) Sleep() yerine SpinWait() kullanmak daha uygun olur.

Sleep() method’u (veya syncronization nesnesi), thread’in CPU üzerinde context switch yapmasına sebep olur.

Son cümle; SpinWait() method’u, çağıran thread’i, işlemci üzerinde aktif tutar, Sleep() method’u ise, thread’i belirli süre boyunca gerçek anlamda uyutur.

C# WMI Örnekler – 1

31 Ekim 2010 1 yorum

Bilgisayardaki Paylaşılan Dizinleri listelemek için; (Win32_Share sınıfını kullanır)

ManagementObjectSearcher mos = new ManagementObjectSearcher("select * from win32_share");
foreach (ManagementObject mo in mos.Get())
{
	Console.WriteLine("Dizin : {0}", mo["Name"]);
}

Bilgisayarda Elle Başlatılan ve Çalışan Servisleri listelemek için; (Win32_Service sınıfını kullanır)

ManagementObjectSearcher mos = new ManagementObjectSearcher("Select * from Win32_Service Where State='Running' AND StartMode='Manual'");
foreach (ManagementObject mo in mos.Get())
{
	Console.WriteLine("Servis : {0}", mo["Name"]);
}

Bilgisayarda o anda Çalışmakta olan Process‘leri listelemek için; (Win32_Process sınıfını kullanır)

ManagementObjectSearcher mos = new ManagementObjectSearcher("Select * from Win32_Process");
foreach (ManagementObject mo in mos.Get())
{
	Console.WriteLine("Process : {0}", mo["Name"]);
}

Bilgisayarda bulunan İşlemcileri (CPU) listelemek için; (Win32_Processor sınıfını kullanır)

ManagementObjectSearcher mos = new ManagementObjectSearcher("Select * from Win32_Processor");
foreach (ManagementObject mo in mos.Get())
{
	Console.WriteLine("Process : {0}", mo["Name"]);
}

Win32 sınıflarının tamamına ve özelliklerine MSDN‘deki Win32 Classes sayfasından ulaşabilirsiniz.

Bilgisayarın WIFI sinyal seviyesini göstermek için; (Technet‘teki makaleden alıntıdır.)

ManagementObjectSearcher mos = new ManagementObjectSearcher(@"root\WMI", "select * from MSNdis_80211_ReceivedSignalStrength");
foreach (ManagementObject mo in mos.Get())
{
	Console.WriteLine("", mo["Ndis80211ReceivedSignalStrength"]);
}

Notebook’ta Kalan Pil Süresini göstermek için; (SystemInformation sınıfını kullanır)

Console.WriteLine("Kalan pil yüzdesi : {0}", SystemInformation.PowerStatus.BatteryLifePercent);

Console.WriteLine("Kalan pil süresi : {0}", SystemInformation.PowerStatus.BatteryLifeRemaining);

Bu kodda ne yanlış var? – 7

31 Ekim 2010 4 yorum

Aşağıdaki kod sayesinde ekrana, listedeki isimleri küçük harflerle yazdırmak istiyorsunuz.

using System;
using System.Collections.Generic;

public class EkranaYazdir
{
	public static void Main()
	{
		List<string> Kisiler = new List<string>();

		Kisiler.Add("AHMET");
		Kisiler.Add("MEHMET");
		Kisiler.Add("AYŞE");
		Kisiler.Add("FATMA");

		/// string elemanları küçük harfe çevir
		Kisiler.ForEach(
			delegate(string k)
			{
				k = k.ToLower();
			}
		);

		/// console'a yaz
		Kisiler.ForEach(
			delegate(string s)
			{
				Console.WriteLine(s);
			}
		);
	}
}

MSDN‘de List<T>.ForEach() sayfasında;

Orjinali; Performs the specified action on each element of the List.

Türkçesi; Listedeki her eleman için belirlenmiş action çalıştırır.

yazısını okudunuz, ve kodun doğru çalışmasını bekliyorsunuz.

Fakat istediğiniz gibi çalışmıyor, sizce problem nedir ve nasıl düzeltilebilir?

Sql Server Tablonun Kolonunun İsmini Değiştirmek

02 Mart 2010 Yorum yapılmamış

Neden olduğunu anlayamadığım bir sebepten dolayı Microsoft tablodaki bir kolonun ismini değiştirmek için bir tool sunmuyor.

Peki bir kolonun ismini değiştirmek istersek ne yapmalıyız?

MSDN‘de yer alan şu makalede anlatıldığı gibi, sp_rename stored procedure‘ünü kullanabiliriz.

Örneğin;

EXEC sp_rename 'TabloAdi.KolonAdi', 'YeniKolonAdi', 'COLUMN';

Üçüncü parametrenin alabileceği diğer değerler;

COLUMN : Bir kolonun yeniden isimlendirileceğini belirtir
DATABASE : Veritabanının yeniden isimlendirileceği durumda kullanılır
INDEX : Kullanıcının oluşturduğu index yeniden isimlendirileceğinde kullanılır

VB.NET’te anahtar kelimeyi değişken ismi olarak kullanma

14 Aralık 2009 Yorum yapılmamış

Daha önce yazdığım C#’ta anahtar kelimeyi değişken ismi olarak kullanma yazımda, aynı işin VB.NET’te nasıl yapılacağını yazmamıştım.

Değişken isminin, dilin anahtar kelimelerinden biri olmasına verbatim identifier deniyor.

MSDN’de C# dili için verbatim identifier nasıl tanımlanır makalesi mevcut, fakat VB.NET için nasıl yapılacağı dökümante edilmemiş.

Hala verbatim identifier tanımlamanın KÖTÜ bir fikir olduğunu düşünüyorum, fakat VB.NET’te verbatim identifier nasıl tanımlanır, merak edenler için;

Dim [String] As String = ""
Dim [For] As Boolean = True
Dim [While] As Integer = 6
Dim [False] As DateTime = DateTime.Now
Dim [ReadOnly] As File

Sql Server ServerProperty Fonksiyonu

26 Kasım 2009 Yorum yapılmamış

Sql Server’ın çalıştığı sunucu ile ilgili özellik bilgilerine sorgu ile erişmek istediğimizde kullanabileceğimiz bir fonksiyon var;

SERVERPROPERTY ( propertyname )

Örnek;

SELECT
	SERVERPROPERTY('edition') AS SURUM,
	SERVERPROPERTY('productlevel') AS SEVIYE,
	SERVERPROPERTY('productversion') AS VERSIYON,
	SERVERPROPERTY('servername') AS SUNUCU_ADI

SERVERPROPERTY fonksiyonunun alabileceği tüm propertyname parametreleri ve açıklamaları için şuradaki MSDN sayfasına bakınız.

C#’ta anahtar kelimeyi değişken ismi olarak kullanma

16 Kasım 2009 Yorum yapılmamış

NET_CLR_Unleashed

Google Kitaplar‘da, şuradan bulabileceğiniz .Net CLR Unleashed kitabından edindiğim bir bilgiyi paylaşmak istiyorum.

CLS (Common Language Specification), CLS-Uyumlu tüm dillerin, anahtar kelimelerin değişken ismi olarak kullanabilmesini sağlayacak bir mekanizma sunmasını ister.

C# dili için bu mekanizma, anahtar kelimenin başına gelen @ işareti ile sağlanır.

@ işareti kullanılarak, şunlar yapılabilir;

int @int = 8;
Console.WriteLine("integer değişken : {0}", @int);
bool @bool = true;
Console.WriteLine("boolean değişken : {0}", @bool);

Bu sayede, anahtar kelime olan “int”, değişken ismi olarak kullanılabildi.

Kaynak : MSDN: C# Keywords, MSDN: CLS, MSDN: What is CLS, Amazon: NET CLR Unleashed