Home Contact RSS

Visual Studio 2010 and .NET Framework 4 Release Candidate

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”

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

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

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

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:

ucfirstMake 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

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

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

.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

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ı

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.
Next entries »