Posts tagged .net framework
Visual Studio 2010 and .NET Framework 4 Release Candidate
Feb 9th
Microsoft announced that Visual Studio 2010 and .NET Framework 4 Release Candidate versions are available for MSDN subscribers as of February 8th, with general availability on February 10th.
http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx
Download links are now published on the web page above.
“The Turkey Test”
Jul 15th
Martin Kulov, a colleague of mine from ProPeople, sent me a blog post regarding something called “The Turkey Test”. If you are a developer who has ever developed some applications with globalization support or at least willing to, do not forget the check the post at http://www.moserware.com/2008/02/does-your-code-pass-turkey-test.html.
HttpPostedFile.FileName browser dependent behaviour
Dec 14th
Even though these kind of variables must have some standards (may be it already has), there are differences in practise. Be careful with the FileName property of HttpPostedFile class when you want to work on a file being uploaded by visitors of your page because the FileName value that you will get on Internet Explorer and Firefox are different.
If your visitor uses Internet Explorer, you will get the local path to the file. E.g.: C:\somefile.txt. However, if your visitor uses Firefox, the FileName value that you will get will be only the file’s name. E.g.: somefile.txt.
To avoid problems, you may have the following check.
string filename = postedFile.FileName;
if (filename.IndexOf('\\') > -1)
{
filename = filename.Substring(filename.LastIndexOf('\\') + 1);
}
else if (filename.IndexOf('/') > -1)
{
filename = filename.Substring(filename.LastIndexOf('/') + 1);
}
BuildManager.CreateInstanceFromVirtualPath
Nov 5th
BuildManager is a class located in System.Web.Compilation namespace and contains a method named CreateInstanceFromVirtualPath. Using this static method, you may create instances of your UserControl, Page, Generic Handler or those kind of stuff. This might be useful in case you need to create some controls on the fly, etc.
The following piece of code shows how to use it.
UserControl instance = (UserControl)System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath("~/Controls/Somefile.ascx", typeof(UserControl));
How to uppercase the first letter of a word or sentence
Nov 1st
When I used to use PHP to develop my web applications, I really loved its basic but useful method named ucfirst. This function is explained using a simple explanation on PHP documentation:
ucfirst — Make a string’s first character uppercase
I believe within all those useful and complex libraries taking place in .NET Framework, it still misses these kind of basic and useful methods. However, the good side is that we can extend it using our custom extension methods.
Because I needed to implement such a feature as PHP offers using ucfirst function, I wrote the following simple extension to achieve the same functionality.
/// <summary>
/// Capitalizes the first letter of the word.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string ToUpperFirst(this string value)
{
if (string.IsNullOrEmpty(value))
{
return string.Empty;
}
if (value.Length > 1)
{
return
string.Format("{0}{1}",
value.Substring(0, 1).ToUpper(),
value.Substring(1).ToLower()
);
}
else
{
return value.ToUpper();
}
}
And this is how to use it:
string val = "something"; val = val.ToUpperFirst(); // result = Something
Makale 16: Remoting Objelerinin Yaşam Süreleri
Sep 16th
Giriş
.NET Remoting uygulamaları üzerinde bulunan, yani Marshal-by-reference tipindeki, remote object’ler Remoting server üzerinde belirli bir süre boyunca tutulurlar ve bu süre sponsorlar ve lease manager tarafından belirlenir. Sponsorlar System.Runtime.Remoting.Lifetime.ISponsor interface’ini implement eden remotable type’lardır. Lease manager ise System.Runtime.Remoting.Lifetime.ILease interface’ini implement eden ve tek görevi remote object’in ne kadar süre memory üzerinde tutulacağı ile ilgili işlemlerin yönetimi olan object’leri ve sponsorları yönetmek ile görevlidir.
.NET Remoting uygulamalarında bu sistemin bulunmasının sebebi Remoting server’ın, kendisine connected durumda olan Remoting client’ları ile iletişim halince olmadan hangi remote object’i ne zaman garbage collection ile memory’de sileceğini bilemeyecek olmasıdır.
Marshal-by-value tipindeki remote object’ler ise instance’ları oluşturulup, tüm object client’a gönderildikten sonra ilk garbage collection’da memory’den silinecek şekilde mark’lanırlar.
Remoting Objesinin Oluşturulması
System.MarshalByRefObject class’ını inherit eden remotable type’lar InitializeLifetimeService method’unu override ederek memory’de ne kadar süre kalacaklarını belirlerler. InitializeLifetimeService method’u System.Runtime.Remoting.Lifetime.ILease tipinde bir object return eder ve bu object’in CurrentState property’si LeaseState.Initial değilse, üzerinde bulunan diğer özelliklerin set edilmesi başarılı olmayacaktır. InitializeLifetimeService method’u remote object üzerindeki method’lardan birisinin ilk kez call edilmesi durumunda otomatik olarak call edilmektedir.
InitializeLifetimeService method’unun kullanımı
using System;
using System.Runtime.Remoting.Lifetime;
namespace Module3.Chapter5.InitializeLifetime
{
public class MyRemotableType : MarshalByRefObject
{
public MyRemotableType() { }
public override object InitializeLifetimeService()
{
ILease lease = (ILease)base.InitializeLifetimeService();
if (lease.CurrentState == LeaseState.Initial)
{
lease.InitialLeaseTime = TimeSpan.FromMinutes(10);
lease.RenewOnCallTime = TimeSpan.FromMinutes(5);
lease.SponsorshipTimeout = TimeSpan.FromMinutes(2);
}
return lease;
}
}
}
ILease interface’ine ait özellikler aşağıdaki tabloda listelenmiştir.
| Property
|
Type | Description |
| CurrentLeaseTime | System.TimeSpan | Remote object’in ne kadar süre sonra memory’den silineceği bilgisini verir. |
| CurrentState | System.Runtime.Remoting.Lifetime.LeaseState | Lease object’inin hangi state’e sahip olduğu bilgisini verir. |
| InitialLeaseTime | System.TimeSpan | Remote object’in başlangıcından itibaren, renew edilmemesi durumunda, ne kadar süre boyunca memory’de kalacağının bilgisidir. |
| RenewOnCallTime | System.TimeSpan | Remote object’in üzerindeki bir method’un call edilmesi durumunda life time’ın ne kadar süre uzatılacağının bilgisidir. |
| SponsorshipTimeout | System.TimeSpan | Sponsor’a remote object’in ne kadar süre daha memory’de kalması sorulduğunda sponsor’un cevabının ne kadar süre bekleneceğinin bilgisidir. |
ILease interface’ine ait method’lar aşağıdaki tabloda listelenmiştir.
| Method Name
|
Type | Description |
| Register | void | Parametre olarak verilen ISponsor object’ini ILease object’i üzerinde register eder. |
| Renew | System.TimeSpan | Remote object’in life time’ını verilen süre boyunca uzatır ve remote object’in yeni expiration time’ını return eder. |
| Unregister | void | Parametre olarak verilen ISponsor object’ini ILease object’i üzerinde unregister eder. |
ILease interface’ine ait InitialLeaseTime, RenewOnCallTime ve SponsorshipTimeout property’leri Remoting configuration file’ı içerisinde de belirtilebilir. Bu yönetimin kullanılması durumunda yalnızca Client Activated Object tipindeki object’lerin life time’ları tanımlanabilir. <lifetime> node’unun tüm attribute’leri opsiyoneldir ve aldıkları değerin yanında, default S olmak üzere, D (day), H (hour), M (minute), S (second) ve ya MS (millisecond) değerlerinden biri eklenerek değer verilirler.
<lifetime> node’unun kullanımı
<configuration>
<system.runtime.remoting>
<application>
<lifetime
leaseTime="10M"
renewOnCallTime="5M"
sponsorshipTimeOut="2M"
leaseManagerPollTime="30S"
/>
</application>
</system.runtime.remoting>
</configuration>
<lifetime> interface’ine ait özellikler aşağıdaki tabloda listelenmiştir.
| Property | Description |
| leaseTime | Remote object’in başlangıcından itibaren, renew edilmemesi durumunda, ne kadar süre boyunca memory’de kalacağının bilgisidir. |
| renewOnCallTime | Remote object’in üzerindeki bir method’un call edilmesi durumunda life time’ın ne kadar süre uzatılacağının bilgisidir. |
| sponsorshipTimeOut | Sponsor’a remote object’in ne kadar süre daha memory’de kalması sorulduğunda sponsor’un cevabının ne kadar süre bekleneceğinin bilgisidir. |
| leaseManagerPollTime | Lease manager lease time’larını kontrol ettikten sonra ne kadar süre beklemelidir bilgisidir. |
Life time yönetimi için bir diğer opsiyon ise System.Runtime.Remoting.Lifetime.LifetimeServices class’ı içerisinde bulunan static property’lerin uygulama başladığında set edilmesidir. LifetimeServices class’ı <lifetime> node’u ile aynı özelliklere sahiptir. Life time property’lerinin bu şekilde belirlenmesi property’lerin set edildiği AppDomain içerisindeki tüm remote object’lerin life time property’lerini bu şekilde set edecektir.
System.Runtime.Remoting.Lifetime.LifetimeServices class’ı kullanımı
LifetimeServices.LeaseTime = TimeSpan.FromMinutes(10);
LifetimeServices.RenewOnCallTime = TimeSpan.FromMinutes(5);
LifetimeServices.SponsorshipTimeout = TimeSpan.FromMinutes(2);
LifetimeServices.LeaseManagerPollTime = TimeSpan.FromSeconds(30);
Remoting Objesinin Yenilenmesi
Remoting server’ları remote object’lerin memory’den ne zaman silineceğini tek başlarına bilemeyeceklerinden remote object’leri silmeden önce sponsor’lara, sırasıyla, remote object’in lease time’ını uzatmak isteyip istemediklerini sorarlar. Remoting server’ı bir sponsordan ILease interface’inin üzerinde bulunan SponsorshipTimeout süresi boyunca cevap alamazsa bu sponsoru otomatik olarak unregister eder ve eğer varsa diğer register edilmiş sponsorlar için de aynı kuralı takip eder.
Register edildiği lease üzerinden her request gelişinde remote object’in lease time’ını 30 saniye daha uzatacak olan bir sponsor şu şekilde yazılır.
MyRemotableType.cs
public class MyRemotableType : MarshalByRefObject
{
public MyRemotableType() { }
}
MyRemotableTypeSponsor.cs
public class MyRemotableTypeSponsor : MarshalByRefObject, ISponsor
{
public MyRemotableTypeSponsor() { }
#region ISponsor Members
public TimeSpan Renewal(ILease lease)
{
return TimeSpan.FromSeconds(30);
}
#endregion
}
Sponsor’un kullanımı
MyRemotableType remoteObject = (MyRemotableType)Activator.GetObject (typeof(MyRemotableType), "tcp://localhost:1234/MyRemotableType.rem");
ILease lease = (ILease) System.Runtime.Remoting.RemotingServices.GetLifetimeService(remoteObject);
MyRemotableTypeSponsor sponsor = (MyRemotableTypeSponsor)Activator.GetObject (typeof(MyRemotableTypeSponsor), "tcp://localhost:1234/MyRemotableTypeSponsor.rem");
lease.Register(sponsor);
Sponsorlara ek olarak, developer istediği durumlarda remote object’in lease time’ını uzatma imkanına sahiptir. Bunun için Remoting client’ın kodu içerisinde RemotingServices.GetLifetimeService method’u kullanılarak ILease object’ine erişilebilir ve ILease class’inin Renew methodu kullanılarak lease time istenilen süre boyunca uzatılabilir.
ILease.Renew method’u kullanımı
MyRemotableType remoteObject = new MyRemotableType();
ILease lease = (ILease)RemotingServices.GetLifetimeService(remoteObject);
lease.Renew(TimeSpan.FromSeconds(30));
Özet
- Life time yönetimi Remoting server’ın, kendi üzerinde bulunan remote object’lerin hala kullanılır olup olmadığını anlaması gerektiği için önemlidir.
- Sponsorlar System.Runtime.Remoting.Lifetime.ISponsor interface’ini implement eden remotable type’lardır.
- Life time initial value’ları configuration dosyası içerisinde <lifetime> node’u kullanılarak yapılabilir.
- Marshal-by-value olarak tanımlanan remotable type’lar instance’ları client’a gönderildikten hemen sonra ilk garbage collection’da memory’den silinecek şekilde flag’lenirler.
Makale 15: Remoting Uygulamalarında Hata Ayıklamak
Jun 14th
Remoting server’ı çoğu durumda üzerinde çalıştığınız bilgisayar üzerinde bulunmayacaktır. Bunun yerine daha güçlü ve stabil server’lar üzerinde çalışmaları tercih edilecektir. Bu da büyük bir ihtimalle server üzerinde Visual Studio’yu install edemeyeceğiniz anlamına gelmektedir.
.NET uygulamalarının remote debugging yöntemi ile debug edilebilmesi için uygulamanın çalıştığı bilgisayar üzerinde Remote Debugging Components olarak adlandırılan add-on’ların kurulu olması gerekmektedir. Bu add-on’lar Visual Studio’nun kurulu olmadığı bilgisayarlar üzerinde de kurulabilir. Bunun için Visual Studio DVD’si içerisindeki \vs\Remote Debugger\x86 klasöründe bulunan exe dosyasının çalıştırılması gerekmektedir.
Remoting server’ının Console Application, Windows Application ve ya IIS üzerinde olması durumunda debugging işlemleri normalde yapıldığı şekilde ve ya process Visual Studio’ya attach edilerek yapılabilir. Windows service’leri ise bu noktada yalnızca attachment yapılarak debug işlemlerinin yapılabilmesine olanak vermektedir.
Farklı bir bilgisayar üzerinde çalışan Remoting server’ının debug edilebilmesi işin Windows service’inin çalıştığı bilgisayar üzerinde sırasıyla şu işlemler takip edilmelidir:
1. Start > Microsoft Visual Studio 2005 > Visual Studio Tools menüsü içerisindeki “Visual Studio 2005 Remote Debugger Configuration Wizard” shortcut’ına tıklayın.
2. Açılan ekranda Next butonuna tıklayın.
3. Sonraki ekranda Remote debugger’ın servis olarak değil sadece çalıştırmanız durumunda çalışması için Run the “Visual Studio 2005 Remote Debugger” service seçeneğini unchecked olarak bırakın.
4. Next butonuna tıklayın.
5. Allow only computers on the local network (subnet) to connect to the remote debugger seçeneğini işaretleyin.
6. Next butonuna tıklayın.
7. Configuration işlemi tamamlandı.
8. Finish butonuna tıklayın.
9. Start > Microsoft Visual Studio 2005 > Visual Studio Tools menüsü içerisindeki “Visual Studio 2005 Remote Debugger” shortcut’ına tıklayın.
10. Visual Studio 2005 Remote Debugger çalışır.
Yukarıdaki işlemler tamamlandıktan sonra Remoting server’ının bulunduğu bilgisayar uzaktan bağlanacak yetkili bilgisayarların debugging işlemi yapmasına izin verecektir. Debug işlemi ise şu şekilde yapılır:
1. Visual Studio’yu çalıştırın.
2. Windows service’inin source code’larının bulunduğu project’i açın.
3. CTRL + ALT + P tuş kombinasyonunu ve ya Debug > Attach to Process… seçeneğine tıklayarak “Attach to Process” ekranını açın.

4. Qualifier seçeneğini Remoting server’ın üzerinde çalıştığı bilgisayar olarak seçin.
5. Refresh butonuna tıklayın.
6. Available processes listesinde bulunan uygulamalar arasından Windows service’inizi seçin. Örneğin geliştirmiş olduğumuz MyFirstRemotingService uygulaması için process ismi MyFirstRemotingService.exe olur.
7. Attach butonuna tıklayın.
8. MyRemotableType.cs dosyası içerisinde debug etmek istediğiniz satırlara Breakpoint’ler ekleyin.
9. Yeni bir MyFirstRemotingClient.exe uygulaması çalıştırın.
10. Visual Studio Breakpoint’inizin bulunduğu satıra geldiğinde debug ekranına geçiş yapar.

UYARI
Debug işlemini yapacak olan client’ın üzerinde logon olmuş user account’unun Remoting server’ının çalıştığı bilgisayar üzerinde bulunan “Debugger Users” user grubunun içerisinde tanımlanmış olması gerekmektedir. Aksi taktirde authorization ile ilgili sorunlarla karşılaşabilirsiniz.
Görüldüğü üzere .NET kendi bilgisayarımız üzerinde bulunmayan .NET uygulamalarını debug edebilmek için gerekli olan tüm esnekliğe sahip. Remoting server’ının kapatılmamasını gerektiren durumlarda bu olanak son derece faydalıdır.
Özet
- Remoting server’ları IIS, Windows Application, Windows Service (NT Service) ve Console Application tipindeki uygulamalar kullanılarak host edilebilir.
- IIS üzerinde host edilen Remoting server’ları yalnızca HTTP protokolünden faydalanabilir.
- Remoting server’ları uzak bilgisayarlardan debug edilebilirler. Bu işleme Remote Debugging adı verilmektedir.
- InstallUtil.exe Windows Service uygulamalarının kurulması için kullanılan bir utility’dir. -u parametresiyle birlikte kullanıldığında service uninstall işlemi için de kullanılabilir.
- Remoting server’larının Windows Service üzerinde host edilmesinin en büyük avantajı yüksek hata management’ı ve otomatik startup olanağıdır. Service’in hata alması durumunda nasıl bir davranış sergileyeceği developer tarafından belirlenebilir.
- Performance monitoring .NET uygulamalarının hangi işlemi ne kadar zamanda yaptığı, AppDomain ve ya tüm .NET uygulamaları içerisinde (seçilen instance değerlerine bağlı olarak) kaç kere Exception throw edildiği gibi birçok runtime bilgisinin kolayca raporlanabilmesi için kullanılmaktadır.
- System.Diagnostics.PerformanceCounter class’ı .NET uygulamaları içinde performance counter data’larına erişilebilmesine imkan tanımaktadır.
Makale 14: Remoting Uygulamalarının “Performance Counter”lar ile İzlenmesi
May 20th
.NET içerisinde bulundurduğu hazır class’lar sayesinde uygulamanızın Windows Performans Monitor ile son derece kolay bir şekilde etkileşim kurabilmesini sağlamaktadır.
Performans Monitor, Control Panel içerisinde bulunan “Administrative Tools” klasörü içinde “Performance” isimli shortcut’a tıklayarak ulaşılır ve ilk açıldığında aşağıdaki görüntüye sahiptir.

Performans Monitor üzerinde yeni bir monitör ekranı açmak istendiğinde “New Counter Set” butonuna tıklanır.

Yeni counter set’inde hiçbir counter bulunmaz. Bu boş counter set’ine yeni performance counter’ları eklemek için “Add” butonuna tıklanır.

Açılan ekranda “Performance object” seçeneği ile ne tip bir performance counter ekleneceği seçilir. .NET ile ilgili performance object’leri ekran görüntüsünde de görüldüğü gibi şu şekildedir:

Add Counters ekranında “Explain” butonuna tıklanarak performance counter hakkında detaylı bilgi alınır:

Instance seçim bölümünde uygulama seçilerek “Add” butonuna tıklanır:

Performance counter eklendikten sonra “Add Counters” ekranı başka performance counter’ların ekleneceği düşünülere kapatılmaz. Kapatılmak istendiğinde “Close” butonuna tıklanır. “Close” butonuna tıklandıktan sonra geri dönülen ekranda bulunan performance counter listesinde eklenmiş olan counter bulunur.

Bu işlemleri yaptıktan sonra seçmiş olunan uygulamaya bağlanacak olan Remoting client’ı run edilir ve ekrandaki değerler gözlemlenir.

Uygulama tekrar çalıştırıldığında değerler kaldığı yerden tekrar artacaktır.

.NET Framework’ün System.Diagnostics namespace’i altında bulunan PerformanceCounter class’ı Performance Monitor uygulamasının ekranda grafiksel olarak gösterdiği bilgilere, uygulamanın programmatic olarak erişebilmesini sağlar. Bu sayede yazılımcılar kendilerine özel performance monitor uygulamaları geliştirebilirler ve ihtiyaçlarına özel raporlar oluşturabilirler.
Daha önceden geliştirmiş olduğumuz MyFirstRemotingService project’i içerisinde bulunan MyRemotableType class’ını aşağıdaki şekilde değiştirerek, uygulamanın RequestCount method’u içerisinde PerformanceCounter class’ını kullanarak aldığı bilgiyi döndürmesini sağlayabiliriz.
MyRemotableType.cs
using System;
using MyFirstRemotableType;
using System.Diagnostics;
namespace MyFirstWindowsService
{
public class MyRemotableType : MarshalByRefObject, IMyRemotableType
{
PerformanceCounter perfCounter;
public MyRemotableType()
{
perfCounter = new PerformanceCounter();
perfCounter.CategoryName = ".NET CLR Remoting";
perfCounter.CounterName = "Total Remote Calls";
perfCounter.InstanceName = "MyFirstWindowsService";
perfCounter.MachineName = Environment.MachineName;
}
public DateTime GetServerDateTime()
{
return System.DateTime.Now;
}
public int RequestCount()
{
return Convert.ToInt32(perfCounter.NextValue());
}
}
}
PerformansCounter class’ının CategoryName özelliği Performance Monitor uygulamasına counter eklerken seçtiğimiz “Performance object” seçeneğine denk gelmektedir. Bu özelliğe “Add Counters” ekranında görmüş olduğunuz herhangi bir değeri string olarak atayabilirsiniz.
PerformansCounter class’ının CounterName özelliği “Add Counters” ekranındaki “Counter” seçeneğine denk gelmektedir. Bu özelliğe “Add Counters” ekranında, “Counters” bölümünde görmüş olduğunuz herhangi bir değeri string olarak atayabilirsiniz.
PerformansCounter class’ının InstanceName özelliği “Add Counters” ekranındaki “Instance” seçeneğine denk gelmektedir ve instance listesinde bulunan uygulamalardan hangilerinin bu counter ile ölçüleceğini belirlemek için kullanılır. Bu özelliğe “Add Counters” ekranında, “Instances” bölümünde görmüş olduğunuz herhangi bir değeri string olarak atayabilirsiniz.
PerformansCounter class’ının MachineName özelliği Performance Monitor uygulamasına counter eklerken seçtiğimiz “Counter” seçeneğine denk gelmektedir. System namespace’inde bulunan Environment class’ının sahip olduğu static access-modifier’ına sahip MachineName özelliği uygulamanın üzerinde çalıştığı bilgisayarın ismini verdiğinden, sabit değer verilmek istenmemesi durumunda bu özelliğin atanması mümkündür.
PerformansCounter class’ının NextValue method’u counter’ın üzerinde gerekli hesaplamaları yaparak hesaplanan değeri geri döndürür.
Makale 13: Remoting Uygulamalarında Hata Ayıklanması ve Dağıtım
May 3rd
Giriş
“Uygulama çok yavaş çalışıyor!” cümlesi bir developer’ın en son duymak isteyeceği cümledir. Bir şekilde duyduysak da artık uykusuz gecelere hoşgeldin demenin vakti gelmiş demek oluyor.
Fakat uykusuz gecelerin sebebi sanıldığı gibi yavaşlıkların sebebinin bulunması değil, optimizasyonların yazılması. Peki nasıl oluyor da yavaşlıkların ve performans kayıplarının bulunması bu kadar olabiliyor diye düşünenler için cevap çok net, Windows’un sunmuş olduğu “Performance Monitor”.
Uygulamalar bazen sadece yoğun olarak çalıştıkları durumlarda, örneğin 10 kullanıcının aynı anda bağlı olması, çeşitli sorunlar çıkartabilirler. Bu durumda uygulamayı debug edebilmek için tek şansınız çalışır halde, uygulamanın client’lara sunduğu servisleri aksatmadan duruma müdahale etmektir. Remoting uygulamalarının debugging işlemi bu sebeplerden dolayı çeşitli sorunlara neden olabilmektedir. Fakat uygun condition’lar oluşturulduğunda bu sorun rahatlıkla aşılabilmektedir.
Remoting’in getirmiş olduğu en önemli avantajın farklı environment’lar kullanılarak host edilebileceği olduğundan bahsetmiştik. Örneğin ASP.NET uygulamaları, Console Application’lar ve ya NT Service’leri. Tüm bu opsiyonları karşılaştırarak en uygun seçeneği bulmanız gerçekten önemli bir konu.
Bu chapter sonunda aşağıdaki konular hakkında bilgi sahibi olacağız;
- Performance Monitor’ü kullanımı,
- Remoting uygulamalarının debug edilmesi,
- Remoting server’ının host edilmesi.
Host and Deploy a Remoting Application
.NET Framework remoting uygulamarının aşağıdaki seçenekler üzerinde host edilmesine imkan tanır.
- IIS
- Windows Service (NT Service)
- Windows Application
- Console Application
IIS
Host seçeneğinin Internet Information Services (IIS) olarak yapılması IIS’in kendi içerisinde bulunan güvenlik seçeneklerinin (SSL, certificates, etc.) uygulamaya herhangi bir ek kodlama gerektirmeden eklenebilmesini sağladığı için avantajlıdır. IIS seçeneği seçildiğinde channel’ın üzerinde çalışacağı protocol yalnızca HTTP olabilir.
Windows Service
Hata oluşması durumunda Windows servislerinin sahip olduğu otomatik tekrar başlama özelliği sayesinde çeşitli hataların oluşması durumlarına karşı en avantajlı seçenektir. Uygun ayarların yapılması durumunda sistemin başlaması sonrasında, herhangi bir kullanıcının logon olmasına gerek olmadan, otomatik olarak çalışma özelliğine sahiptir.
Windows Service’leri System.ServiceProcess.ServiceBase class’ından inherit edilerek yazılmaları gerekmektedir. OnStart ve OnStop method’larının override edilmesi durumunda servisin başlatılmasında ve durdurulmasında yapılacak olan işlemler kolaylıkla develop edilebilir.
Windows Application
Uygulamanın çeşitli parametrelere göre test edilmesi gibi durumlar sözkonusu olduğunda sunduğu görsel arabirim çeşitli avantajlar getirebilmektedir. Uygulamanın kapanmasına sebep olacak bir exception throw edilmesi durumunda otomatik tekrar başlama şansı olmadığı için production environment’ta kullanılmamalıdırlar. Fakat Windows Application’ları genellikle Remoting server yerine Remoting client development’ında kullanılırlar.
Console Application
Test aşamalarında kolay olarak çalıştırılabilmesi ve kolay debug edilebilmesi sebebiyle kullanılabilir. Remoting server’ları genel olarak bu uygulama tipinde develop edildikten sonra Windows Service uygulaması haline convert edilirler.
Örnek Windows Service Uygulaması
1. Visual Studio’yu çalıştırın.
2. File > New menüleri altındaki Project seçeneğini seçin.
3. Visual C# > Windows seçeneği altındaki Windows Service proje tipini seçin.
4. Name property’sine MyFirstWindowsService yazın.
5. Location property’sine projeyi oluşturmak istediğiniz klasörün path’ini yazın ve ya Browse seçeneğini kullanarak path’i gösterin.
6. Solution Name property’si otomatik olarak MyFirstWindowsService şeklinde değişir, eğer değişmemiş ise bu property’ye de MyFirstWindowsService yazın.
Bu işlemler sonrasında New Project ekranı aşağıdaki şekilde görünür:

NOT
Location property’sinde yazmakta olan “C:\Path\to\Your\Project” path’i seçmiş olduğunuz path’e göre değişiklik gösterektir.
7. OK butonuna tıklayın.
8. Karşınıza “Service1.cs” isimli bir dosya açık olacak çıkar.

9. Bu dosyanın ismini Solution Explorer penceresi yardımı ile “MyFirstService.cs” olarak değiştirin.
10. Visual Studio “Service1.cs” dosyasının ismini değiştirdikten sonra bu dosya içerisindeki “Service1″ isimli class’ın ismi otomatik olarak “MyFirstService” şeklinde değişir. Değişmemesi durumunda class’ın ismini “MyFirstService” olarak değiştirin.
11. Solution Explorer penceresindeki References klasörüne sağ tıklayarak “Add Reference” seçeneğine tıklayın.
12. Karşınıza “Add Reference” penceresi çıkar. Bu pencerede “.NET” tab’ındaki “System.Runtime.Remoting” assembly’sini seçin ve OK butonuna tıklayın.

13. Solution Explorer penceresindeki References klasörüne sağ tıklayarak “Add Reference” seçeneğine tıklayın.
14. Karşınıza “Add Reference” penceresi çıkar. Bu pencerede “Browse” tab’ını seçerek “MyFirstRemotableType” project’inin bulunduğu klasöre gidin.

15. Bu klasör içerisinde de sırasıyla “bin” ve “Debug” klasörlerine girerek “MyFirstRemotableType.dll” isimli assembly’yi seçin ve OK butonuna tıklayın.

16. Project’e MyRemotableType.cs isminde yeni bir Class dosyası ekleyin.
17. MyRemotableType.cs dosyasının içeriğini daha önce develop etmiş olduğumuz MyFirstRemotingServer projesindeki ile aynı fakat tek farkı namespace bilgisi “MyFirstWindowsService” olarak, aşağıdaki şekilde yazın:
MyFirstService.cs dosyasına import edilecek namespace’lerin import edilişleri
using System;
using MyFirstRemotableType;
namespace MyFirstWindowsService
{
public class MyRemotableType : MarshalByRefObject, IMyRemotableType
{
int requestCount;
public MyRemotableType()
{
this.requestCount = 0;
}
public DateTime GetServerDateTime()
{
requestCount++;
return System.DateTime.Now;
}
public int RequestCount()
{
return requestCount;
}
}
}
18. MyFirstService.cs isimli dosyaya sağ tıklayarak “View Code” seçeneğine tıklayın. Karşınıza servisin kodları çıkar.
19. MyFirstService.cs dosyası içerisinde aşağıdaki namespace’leri import edin:
MyFirstService.cs dosyasına import edilecek namespace’lerin import edilişleri
using System;
using System.Collections;
using System.ServiceProcess;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using MyFirstRemotableType;
20. OnStart method’unu aşağıdaki şekilde yazın:
OnStart method’u implementation’ı
protected override void OnStart(string[] args)
{
IDictionary channelProperties = new Hashtable();
channelProperties.Add("name", "MyTcpChannelName");
channelProperties.Add("port", "4444");
channelProperties.Add("priority", "1");
TcpChannel tcpChannel = new TcpChannel(channelProperties, new BinaryClientFormatterSinkProvider(), new BinaryServerFormatterSinkProvider());
ChannelServices.RegisterChannel(tcpChannel, false);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyRemotableType), "MyRemotableType.rem", WellKnownObjectMode.Singleton);
}
21. OnStop method’u içeriğinde herhangi bir değişiklik gerekmemektedir.
22. MyFirstService.cs dosyasına sağ tıklayarak “View Designer” seçeneğine tıklayın.
23. Karşınıza gelen ekranda sağ tıklayarak “Add Installer” seçeneğine tıklayın.

24. Ekranda iki yeni object belirir.

25. serviceProcessInstaller1 ismindeki object’in type’ı System.ServiceProcess.ServiceProcessInstaller class’ıdır ve Account özelliği sayesinde servisin hangi user account’unu kullanarak çalıştırılacağı belirlenebilir. Bu özellikler User, LocalService, LocalSystem ve ya NetworkService seçeneklerinden birisi olabilir.
26. serviceInstaller1 ismindeki object’in type’ı System.ServiceProcess.ServiceInstaller class’ıdır ve servisin Description, DisplayName, StartType, ServiceName gibi özelliklerine sahiptir.
27. serviceProcessInstaller1 object’inin Account özelliğini “LocalService” olarak değiştirin.
28. serviceInstaller1 object’inin Description özelliğini “This service hosts my first remoting server” olarak değiştirin.
29. serviceInstaller1 object’inin DisplayName özelliğini “My First Remoting Server” olarak değiştirin.
30. serviceInstaller1 object’inin StartType özelliğini “Automatic” olarak değiştirin.
31. serviceInstaller1 object’inin ServiceName özelliğini “MyFirstRemotingServer” olarak değiştirin.
32. Project’i “Build” menüsünü kullanarak build edin.
33. Visual Studio’yu kapatın.
34. Visual Studio 2005 Command Prompt’u açın.
35. InstallUtil.exe C:\Path\to\Your\Project\bin\Debug\MyFirstWindowsService.exe komutunu yazarak çalıştırın.
NOT
1. InstallUtil.exe uygulaması Windows Service’lerinin kurulması işlemini gerçekleştirmektedir.
2. InstallUtil.exe -u parametresi ile kullanıldığında servisi uninstall etmektedir.
3. Komut içerisinde verilen C:\Path\to\Your\Project path’i project’inizi oluşturduğunuz klasöre uygun olarak değiştirilmelidir.
36. Komut çalıştırıldığında karşınıza servisin hangi user account’unu kullanarak çalıştırılmak istendiği sorusu sorulacaktır. Buraya uygun bilgileri girin.

37. Bilgileri girip OK butonuna tıklayın.
38. Başarılı bir kurulum sonrasında command prompt şu mesajı gösterecektir: “The Commit phase completed successfully. The transacted install has completed.”
39. Control Panel’e gidin.
40. Administrative Tools klasörüne girin.
41. Services shortcut’ına çift tıklayın.

42. Service listesi içerisinde My First Remoting Server isimli service’in yer aldığını göreceksiniz.

43. Service’i çalıştırmak için sağ tıklayın ve Start seçeneğine tıklayın.
44. Service başlatılacaktır.
45. MyFirstRemotingClient isimli console application’ını çalıştırın ve bu işlem sırasında MyFirstRemotingServer isimli console application’ının çalışmadığından emin olun. Bunun sebebi her iki uygulamanın da 4444. portu kullanıyor olması ve ikisinin aynı anda çalışamayacak olmasıdır.
46. MyFirstRemotingServer uygulaması çalışmıyor olduğu halde Remoting client’ı çalışacaktır.
47. My First Remoting Server isimli service’i stop edin.
48. MyFirstRemotingClient isimli console application’ını tekrar çalıştırın.
49. Windows servisini durdurduğumuz durumda MyFirstRemotingClient isimli console application’ının çalışmadığını gördünüz.
Makale 12: Sunucu Uygulamasındaki Bir Methodun Senkronize Olarak Çağırılması
Apr 25th
Remote object’in instance’ının Remoting server’ı üzerinde oluşturulup Remoting client’a gönderilmesinin ardından Remoting client’ı üzerinde referansı tutulan object Remoting client üzerinde aynen local bir object gibi kullanılabilir. Remoting server’da bulunan ve Remoting client’ında sadece referansı tutulan bu object’lerin herhangi bir method’u call edildiğinde bu işlem tamamiyle Remoting server’ı üzerinde çalışacaktır.
Öncelikle daha önceki makalelerde yazmış olduğumuz Remoting server’ın host ettiği MyRemotableType class’ının özelliklerini hatırlayalım.
| Class: MyRemotableType
Access modifier: public |
|||
| Access Modifier
|
Return Type | Name | Purpose |
| public | DateTime | GetServerDateTime | DateTime class’ının Now property’sini döndürecektir ve RequestCount method’unun döndüreceği requestCount field’ının değerini bir değer arttıracak method’dur. |
| public | int | RequestCount | requestCount field’ının çalıştırılma zamanındaki değerini geri göndürecek olan method’dur. |
Tablo 3.1.2
Remoting Server’ın Development’ı
1. Visual Studio’yu çalıştırın.
2. File > New menüleri altındaki Project seçeneğini seçin.
3. Visual C# > Windows seçeneği altındaki Console Application proje tipini seçin.
4. Name property’sine MyFirstRemotingClient yazın.
5. Location property’sine projeyi oluşturmak istediğiniz klasörün path’ini yazın ve ya Browse seçeneğini kullanarak path’i gösterin.
6. Solution Name property’si otomatik olarak MyFirstRemotingClient şeklinde değişir, eğer değişmemiş ise bu property’ye de MyFirstRemotingClient yazın.
Bu işlemler sonrasında New Project ekranı aşağıdaki şekilde görünür:

NOT
Location property’sinde yazmakta olan “C:\Path\to\Your\Project” path’i seçmiş olduğunuz path’e göre değişiklik gösterektir.
7. OK butonuna tıklayın.
8. Karşınıza “Program.cs” isimli bir dosya açık olacak çıkar.

9. Bu dosyanın ismini Solution Explorer penceresi yardımı ile “MyRemotingClient.cs” olarak değiştirin.

10. Visual Studio “Program.cs” dosyasının ismini değiştirdikten sonra bu dosya içerisindeki “Program” isimli class’ın ismi otomatik olarak “MyRemotingClient” şeklinde değişir. Değişmemesi durumunda class’ın ismini “MyRemotingClient” olarak değiştirin.
11. Solution Explorer penceresindeki References klasörüne sağ tıklayarak “Add Reference” seçeneğine tıklayın.

12. Karşınıza “Add Reference” penceresi çıkar. Bu pencerede “.NET” tab’ındaki “System.Runtime.Remoting” assembly’sini seçin ve OK butonuna tıklayın.

13. Solution Explorer penceresindeki References klasörüne sağ tıklayarak “Add Reference” seçeneğine tıklayın.
14. Karşınıza “Add Reference” penceresi çıkar. Bu pencerede “Browse” tab’ını seçerek “MyFirstRemotableType” project’inin bulunduğu klasöre gidin.

15. Bu klasör içerisinde de sırasıyla “bin” ve “Debug” klasörlerine girerek “MyFirstRemotableType.dll” isimli assembly’yi seçin ve OK butonuna tıklayın.

16. MyRemotingClient.cs dosyası içerisinde aşağıdaki namespace’leri import edin:
MyRemotingClient.cs dosyasına import edilecek namespace’lerin import edilişleri
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using MyFirstRemotableType;
17. MyRemotingClient class’ının access modifier’ını public olarak ayarlayın.
MyRemotingClient class’ının “public” access modifier’ına sahip olarak ayarlanması
public class MyRemotingClient
18. Remote object’in instance’ını IMyRemotableType type’ındaki object’e atayın ve bu object’in üzerindeki GetServerDateTime method’unu call ederek dönen değeri command prompt’a yazdırın.
Remote Object’in instance’ına erişimlesi
IMyRemotableType remoteObject = (IMyRemotableType)Activator.GetObject (typeof(IMyRemotableType), "tcp://localhost:4444/MyRemotableType.rem");
Console.WriteLine(remoteObject.GetServerDateTime());
19. Remoting server’ınızı ENTER tuşuna basıldığında programı sonlandıracak şekilde ilgili kodu yazın.
Console Application'un ENTER tuşu ile sonlandırılması
Console.WriteLine("Press ENTER to exit.");
Console.ReadLine();
20. Build menüsünü kullanarak project’i build edin.

21. Bu işlem sonrasında Visual Studio’nun sol alt köşesinde “Build succeeded” yazısı belirir.

22. Visual Studio’yu kapatın.
Remoting Client’ının Çalıştırılması
1. Start menüsü içerisinde bulunan “Run” kısayoluna tıklayın ve karşınıza çıkan ekrana “cmd” yazarak OK butonuna tıklayın.
2. Açılan ekranda command prompt’a cd command’ını kullanarak MyFirstRemotingClient project’inizin bulunduğu klasöre, oradan da sırasıyla “bin” ve “Debug” klasörlerine girin.
3. İlgili klasörlere girdikten sonra command prompt’a “MyFirstRemotingClient.exe” yazarak ENTER tuşuna basın.
4. Bilgisayarınızda herhangi bir firewall uygulaması yüklü olması durumunda karşınıza “MyFirstRemotingClient” uygulamasının internet ve ya network üzerinden bağlantı sağlamasının block’landığına dair bir mesaj gelebilir.
5. Bu durumda uygulamanın unblock edilmesi gerekir.
6. Uygulamanın düzgün çalışması durumunda command prompt’ta Remoting server’ın üzerinde çalıştığı bilgisayarın tarih ve saat bilgileri ile birlikte “Press ENTER to exit.” yazısı belirir.
Özet
- Remote object’ler Remoting server üzerinde create edildikten sonra instance’ları Remoting client’larına gönderilen ve client üzerinde bu object üzerinde bir işlem yapılması durumunda işlem object’in Marshal-by-ref olması durumunda Remoting server’ı üzerinde execute edilecektir.
- Remoting client’ları hem configuration file kullanılarak hem de programmatic olarak configure edilebilmektedir. Fakat remote object’ler Activator class’ının GetObject method’u kullanılarak erişilebilirler.