Create | Engin Polat\'ın Windows 8 , Windows Phone 8 ve C# içerikli programcılık sitesi

Arşiv

Etiketlenen yazılar create

C# ile uzun süren method’ları kontrol altına alın

18 October 2013 Yorum yapılmamış

Uygulama geliştirirken karşılaştığımız birçok senaryoda çağırdığımız bir method’un uzun sürede cevap üretmemesinden dolayı kaynaklarımızı tükettiğini görebiliriz.

Çağırılan method’un belli bir zaman aşımı süresine sahip olması ve bu süre sonuna kadar değer üretmediyse sonlanması için birçok yöntem kullanabiliriz, fakat ben System.Threading namespace‘inde yeralan CancellationTokenSource sınıfını kullanan aşağıdaki yöntemi tercih ediyorum;

/// <summary>
/// Timeout süresinde tamamlanmayan method'u otomatik sonlandırır
/// </summary>
/// <param name="action">Çağırılacak method</param>
/// <param name="timeout">Milisaniye cinsinden zamanaşımı süresi</param>
/// <returns></returns>
public static bool Execute(Action action, int timeout)
{
	var tokenSource = new CancellationTokenSource();

	var token = tokenSource.Token;

	var task = Task.Factory.StartNew(action, token);

	if (!task.Wait(timeout, token))
	{
		tokenSource.Cancel();

		return false;
	}

	task.Dispose();

	return true;
}

/// <summary>
/// Timeout süresinde tamamlanmayan method'u otomatik sonlandırır
/// </summary>
/// <param name="action">Çağırılacak method</param>
/// <param name="timeout">Milisaniye cinsinden zamanaşımı süresi</param>
/// <returns></returns>
public static Tuple<bool, T> Execute<T>(Func<T> action, int timeout)
{
	var result = Tuple.Create(false, default(T));

	var tokenSource = new CancellationTokenSource();

	var token = tokenSource.Token;

	var task = Task.Factory.StartNew(() => { result = Tuple.Create(true, action.Invoke()); }, token);

	if (!task.Wait(timeout, token))
	{
		tokenSource.Cancel();
	}

	task.Dispose();

	return result;
}

Böylece değer döndürmeyen method’lar eğer timeout‘a uğramışsa geriye bool tipinde false değeri, timeout‘a uğramamışsa true değeri döndürebiliyoruz.

Geriye değer döndürecek method’lar eğer timeout‘a uğramışsa geriye Tuple sınıfından yeni bir değer döndürüyoruz. İki property’li Tuple‘ın birinci property’si timeout olup/olmadığını belirten bool tipinde, ikinci property ise çağırılan method’dan dönecek cevabın tipinin varsayılan değeri.

Bu methodlar sayesinde hatalar veya uzun süren method’ların kaynaklarımızı tüketmesi sorunları ile uğraşmadan uygulamalarımızı geliştirebiliriz.

Örnek kullanımlar;

Geriye değer döndürmeyen method’ları aşağıdaki örnek kullanım ile çağırabiliriz

var result = Execute(LongRunningProcess, 3000);

Geriye değer döndüren method’ları (örneğin int) aşağıdaki örnek kullanım ile çağırabiliriz

var result = Execute<int>(LongRunningProcess, 5000);

Dosya boyutu almak için Head isteğinde bulunmak

05 October 2011 1 yorum

Uygulamalarımızda internet üzerindeki bir dosyanın boyut bilgisine ihtiyacımız olabilir.

Yapmamız gereken; dosyaya istekte bulunup Length özelliğinden dosya boyutu bilgisini almak.

var DosyaKonum = "http://www.enginpolat.com/wp-content/uploads/2011/07/FPSOrnek.rar";

WebClient wc = new WebClient();
var Dosya = wc.DownloadData(DosyaKonum);

int DosyaBoyut = Dosya.Length;

Bu yöntemin en önemli dezavantajı, dosyanın boyut bilgisini alabilmek için dosyayı gerçekten download etmemiz gerekiyor. Özellikle büyük boyutlu dosyalarda bu yöntem büyük problemlere yol açacaktır.

Aslında yapılan isteğin sonucunun Başlık (Header) bilgisinde dosya boyutu yer alıyor. Eğer Başlık‘tan (Header) boyut bilgisine ulaşabilirsek dosyayı download etmemize gerek kalmaz.

var DosyaKonum = "http://www.enginpolat.com/wp-content/uploads/2011/07/FPSOrnek.rar";

var Request = WebRequest.Create(DosyaKonum);

Request.Method = "HEAD";

var Response = Request.GetResponse();

var DosyaBoyut = Response.Headers[HttpResponseHeader.ContentLength];

Öncelikle WebRequest sınıfının static Create() method’u sayesinde, parametresinde adresi verilmiş dosyaya bir istek oluşturuyoruz.

Request değişkeninin GetResponse() method’undan sonuç bilgisini almadan önce Method özelliğine HEAD değerini atıyoruz.

Böylece istek sonucunda, dosyanın içeriğinin değil sadece başlık bilgisinin bulunmasını sağlıyoruz.

HttpResponseHeader enum’ında yeralan ContentLength değeri ile Response değişkeninin Headers özelliğinden dosyanın boyut bilgisine ulaşabiliyoruz.

Bu kodda ne yanlış var? – 9

20 August 2011 12 yorum

Geliştirmekte olduğumuz bir projede C:\ sürücüsünde bulunan OnemliDosya.xls dosyasını sıkışırmamız ve OnemliDosya.zip dosyasını oluşturmamız istendi.

Hemen arkasından sıkıştırdığımız dosyayı açmamız ve OnemliDosya.Yeni.xls dosyasını oluşturmamız bekleniyor.

Aşağıdaki method’ları bu görev için yazdık;

public static void Compress(string ZiplenecekDosyaAdi, string ZipDosyaAdi)
{
	FileStream InputStream = File.Open(ZiplenecekDosyaAdi, FileMode.Open);
	FileStream OutputStream = File.Open(ZipDosyaAdi, FileMode.Create);
	GZipStream ZipStream = new GZipStream(OutputStream, CompressionMode.Compress);

	try
	{
		byte[] Buffer = new byte[InputStream.Length];
		InputStream.Read(Buffer, 0, Buffer.Length);
		ZipStream.Write(Buffer, 0, Buffer.Length);
	}
	finally
	{
		OutputStream.Close();
		InputStream.Close();
	}
}

public static void Decompress(string ZiplenecekDosyaAdi, string ZipDosyaAdi)
{
	FileStream Input = File.Open(ZiplenecekDosyaAdi, FileMode.Open);
	FileStream Output = File.Open(ZipDosyaAdi, FileMode.Create);
	GZipStream ZipStream = new GZipStream(Input, CompressionMode.Decompress);

	try
	{
		int Data = ZipStream.ReadByte();
		while (Data > 0)
		{
			Output.WriteByte((byte)Data);
			Data = ZipStream.ReadByte();
		}
	}
	finally
	{
		Output.Close();
		Input.Close();
	}
}

Yazdığımız method’ları aşağıdaki gibi kullanıyoruz;

Compress("C:\\OnemliDosya.xls", "C:\\OnemliDosya.zip");
Decompress("C:\\OnemliDosya.zip", "C:\\OnemliDosya.Yeni.xls");

Kodumuzdan emin olmamıza rağmen, çalışmadığını farkediyoruz.

Sizce problem nedir ve nasıl düzeltilebilir?

C# ile Geçici Dosya (Temporary File) oluşturma sınıfı yazalım

13 July 2011 Yorum yapılmamış

Projelerimizde dosya sistemi üzerinde geçici olarak dosya oluşturma ve işimiz bittiğinde silme ihtiyacı hissedebiliriz.

Bu yazıyı okumadan önce Hem benzersiz hem de geçici dosya oluşturmanın en kolay yolu ve C# ile Geçici Dosya Oluşturmak başlıklı yazılarımı okumanızı öneririm.

Bu linkte bulduğum yöntemi çok kullanışlı buldum ve sizler (aynı zamanda kendim) için türkçeleştirdim;

public class TempFile : IDisposable
{
	public TempFile() : this(string.Empty)
	{ }

	private readonly string _tmpfile;

	public TempFile(string extension)
	{
		_tmpfile = Path.GetTempFileName();

		if (!string.IsNullOrEmpty(extension))
		{
			string newTmpFile = _tmpfile + extension;

			/// Yeni bir geçici dosya oluşturulur
			File.Create(newTmpFile, 0);
			/// Eski geçici dosya silinmediyse, silinir.
			File.Delete(_tmpfile);

			/// Yeni oluşturulan geçici dosya kullanıma hazır!
			_tmpfile = newTmpFile;
		}
	}

	public string FullPath
	{
		get { return _tmpfile; }
	}

	void IDisposable.Dispose()
	{
		if (!string.IsNullOrEmpty(_tmpfile) && File.Exists(_tmpfile))
		{
			File.Delete(_tmpfile);
		}
	}
}

Kullanımına örnek;

using(TempFile tmp = new TempFile(".dat")) /// dat uzantılı bir geçici dosya oluşturuluyor
{
	/// FullPath özelliğinden geçici dosyanın yolu ve dosya adı alınabilir;
	string filename = tmp.FullPath;
}

Sql Server 2008 Except ve Intersect Anahtar Kelimeleri

03 May 2011 Yorum yapılmamış

Sql Server 2008, T-SQL diline yapılmış birkaç ek geliştirme ile birlikte geldi. Daha önce yazdığım şu makaleden SQL Server 2008 MERGE operatörü hakkında bilgi alabilirsiniz.

Bugün yazacağım yazı ile EXCEPT ve INTERSECT operatörlerini inceleyeceğim.

Hem EXCEPT, hem de INTERSECT operatörü iki farklı sorgunun karşılaştırılması ve bir sonuç kümesi döndürülmesi ilkesi ile çalışır.

t-sql intersect ve except

EXCEPT anahtar kelimesi ile, bir sorgunun sonuç kümesinde olan, fakat diğer sorgunun sonuç kümesinde kesinlikle olmayan kayıtları buluruz.

TABLO1’de bulunup, TABLO2’de bulunmayan kayıtlar

SELECT * FROM TABLO1
EXCEPT
SELECT * FROM TABLO2

TABLO2’de bulunup, TABLO1’de bulunmayan kayıtlar

SELECT * FROM TABLO2
EXCEPT
SELECT * FROM TABLO1

INTERSECT anahtar kelimesi ile ise, her iki sorgunun sonuç kümesinde de kesinlikle olan kayıtları bulabiliriz.

Hem TABLO1’de bulunup, hem de TABLO2’de bulunan kayıtlar

SELECT * FROM TABLO1
INTERSECT
SELECT * FROM TABLO2

Bir örnek ile daha iyi anlaşılacak. Öncelikle Personel ve Stajer tablolarımızı oluşturalım.

CREATE TABLE dbo.Personel
(
	ID INT NOT NULL IDENTITY,
	AdSoyad VARCHAR(100) NOT NULL,
	SicilNo CHAR(6) NOT NULL,
	EMail VARCHAR(100) NOT NULL,
	IseGirisTarihi SMALLDATETIME NOT NULL,
	YoneticiID INT NOT NULL,
	DepartmanID NOT NULL
)
CREATE TABLE dbo.Stajer
(
	ID INT NOT NULL IDENTITY,
	AdSoyad VARCHAR(100) NOT NULL,
	StajerNo CHAR(6) NOT NULL,
	EMail VARCHAR(100) NOT NULL,
	StajBaslangicTarihi SMALLDATETIME NOT NULL,
	YoneticiID INT NOT NULL,
	StajDepartmanID NOT NULL
)

İlk olarak, staj yapmamış personel’in adını seçeceğimiz sorguyu yazalım;

SELECT AdSoyad FROM dbo.Personel
EXCEPT
SELECT AdSoyad FROM dbo.Stajer

İkinci olarak, işe başlamamış olan stajer’lerin adını seçeceğimiz sorguyu yazalım;

SELECT AdSoyad FROM dbo.Stajer
EXCEPT
SELECT AdSoyad FROM dbo.Personel

Son olarak, hem staj yapıp, hem de işe başlamış olan personel’in adını seçeceğimiz sorguyu yazalım;

SELECT AdSoyad FROM dbo.Personel
INTERSECT
SELECT AdSoyad FROM dbo.Stajer