17 Temmuz 2018 Salı

msbuild komutu

/p:Configuration seçeneği
Release, Debug seçeneklerini alabilir.

Örnek
Şöyle yaparız.
msbuild /p:Configuration=Release BigProject.sln
Örnek
Şöyle yaparız.
msbuild DesignService.csproj /m /p:Configuration="Debug" /p:Platform="AnyCPU" 
  /verbosity:quiet /t:Package /p:PackageLocation=X.zip /p:PackageAsSingleFile=True

16 Temmuz 2018 Pazartesi

AppDomainSetup Sınıfı

Örnek
Şöyle yaparız.
var domainSetup = new AppDomainSetup()
{
  ShadowCopyDirectories = "true",
  ShadowCopyFiles = "true",
  ApplicationName = Assembly.GetExecutingAssembly().ManifestModule.ScopeName,
  DynamicBase = assemmblyDir,
  LoaderOptimization = LoaderOptimization.MultiDomainHost,
};
_domain = AppDomain.CreateDomain("Isolated:" + Guid.NewGuid(), null, domainSetup);

15 Temmuz 2018 Pazar

TimeZoneInfo Sınıfı

Giriş
Bu sınıf tüm dünyadaki saat dilimlerini temsil eder. .NET 4.0'dan beri mevcut. Bilgisayarın yerel saat dilimine erişmek için TimeZone sınıfı kullanılır.

BaseUTcOffset alanı
Açıklaması şöyle.
TimeZoneInfo.BaseUtcOffset property is the difference between UTC and the time zone's standard time, not the actual time.
Örnek
Şöyle yaparız.
var zone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
var baseOffset = zone.BaseUtcOffset; // UTC-06:00
var actualOffset = zone.GetUtcOffset(DateTime.UtcNow); // UTC-05:00
ConvertTime metodu
İlk parametre olarak yerel zaman, ikinci parametre olarak hedef zaman dilimi verilir. Çağrı yerel zamanı hedef zaman dilimine çevirir.

Örnek ver.

ConvertTimeFromUtc metodu - DateTime + TimeZoneInfo
İlk parametre olarak UTC zaman, ikinci parametre olarak hedef zaman dilimi verilir. Çağrı UTC zamanı hedef zaman dilimine çevirir.

Eğer DateTime nesnesinin Kind alanı UTC değilse şu exception fırlatılır.
at System.TimeZoneInfo.ConvertTime(DateTime dateTime, TimeZoneInfo sourceTimeZone, TimeZoneInfo destinationTimeZone, TimeZoneInfoOptions flags, CachedData cachedData) at System.TimeZoneInfo.ConvertTimeFromUtc(DateTime dateTime, TimeZoneInfo destinationTimeZone)
The conversion could not be completed because the supplied DateTime did not have the Kind property set correctly. For example, when the Kind property is DateTimeKind.Local, the source time zone must be TimeZoneInfo.Local.
Örnek
Şöyle yaparız.
DateTime timeUtc = ...;
TimeZoneInfo cstZone = ...;
DateTime cstTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, cstZone);
Örnek
Şöyle yaparız.
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
var utcNow = DateTime.UtcNow;
var localTime = TimeZoneInfo.ConvertTimeFromUtc(utcNow, timeZone);
Console.WriteLine(localTime.ToShortDateString());
Örnek
Şöyle yaparız.
TimeZoneInfo.ConvertTimeFromUtc(utcdate, clients_timezoneinfo)
ConvertTimeToUtc metodu
Yerel zamanı UTC zamana çevirir.

FindSystemTimeZoneById metodu
Örnek
Şöyle yaparız.
string zoneId = "AUS Eastern Standard Time";
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(zoneId);
Örnek
Şöyle yaparız.
string zoneId = "Central Standard Time";
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(zoneId);
Örnek
Şöyle yaparız.
string zoneId = "New Zealand Standard Time";
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(zoneId);
Örnek
Şöyle yaparız.
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
GetUtcOffset metodu
Belirtilen zaman dilimi ile UTC arasındaki saat farkını verir.
var utcOffset = TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow);
IsAmbigousTime metodu
Şöyle yaparız.
var result = timeZoneInfo.IsAmbiguousTime(
   new DateTime(2016, 04, 02, 16, 00, 00, 0, DateTimeKind.Utc)
);
Console.WriteLine(result);  // True
StandartName Alanı
Şöyle yaparız.
Console.WriteLine($"{TimeZoneInfo.Local.StandardName}");

9 Temmuz 2018 Pazartesi

async ve await

Giriş
await, async ile beraber ya da tek başına kullanılabilir.

await Tek Başına
await asenkron bir işin bitmesini bekle olarak düşünülebilir. await olmadan asenkron işin Result alanına erşimek doğru değil.

Örnek
İkisinin farkını MSDN şöyle bir örnekle gösteriyor.
async Task<int> AccessTheWebAsync()
{ 
  HttpClient client = new HttpClient();
  Task<string> getStringTask = client.GetStringAsync("http://...");

  DoIndependentWork();

  string urlContents = await getStringTask;

  return urlContents.Length;
}
Tek başına kullanılmasının açıklaması şöyle
If AccessTheWebAsync doesn't have any work that it can do between calling GetStringAsync and awaiting its completion, you can simplify your code by calling and awaiting in the following single statement.
Eğer arada DoIndenpendentWork() metoduna ihtiyaç yoksa sadece şöyle yaparız.
string urlContents = await client.GetStringAsync();
Örnek
pull based ve push based iki işin farkı gibi de düşünülebilir. pull based tost için şöyle yaparız.
// I want some toast.  I will pull it out of the toaster when it is done.
// I will do nothing until the toast is available.
Toast t = toaster.MakeToast();
t.AddJam();
// Yum.
push based tost için şöyle yaparız.
// I want some toast.  But it might take a while and I can do more work
// while I am waiting:
Task<Toast> task = toaster.MakeToastAsync();
Toast t = await task;
// await returns to the caller if the toast is not ready, and assigns
// a callback. When the toast is ready, the callback causes this method
// to start again from this point:
t.AddJam();
// Yum.
Örnek
Elimizde şöyle bir kod olsun.
var user = await _userRepo.GetByUsername(User.Identity.Name);

//Some minor work that doesn't rely on the user object

user = await _userRepo.UpdateLastAccessed(user, DateTime.Now);

return user;
GetByUserName paralel çalışırken ane kod  devam etsin istersek şöyle yaparız.
var userTask = _userRepo.GetByUsername(User.Identity.Name);    
//Some work that doesn't rely on the user object    
user = await _userRepo.UpdateLastAccessed(await userTask, DateTime.Now);    
return user;
userTask'ı await ile beklemek gerekir. Şu kod yanlış çünkü userTask'ın Result alanına eriştiğimizde henüz bitmemiş olabilir.
var userTask = _userRepo.GetByUsername(User.Identity.Name);

//Some work that doesn't rely on the user object

user = await _userRepo.UpdateLastAccessed(userTask.Result, DateTime.Now);

return user;
async Return Type
async metodlar genelde Task, Task<T> veya void dönerler.

async ve await ikilisi
async ve await Continuation yapılacağı zaman kullanılır.  Yani şu async işaretli bir metod içinde bulunan şu kod parçası
var str = await SomeFuncAsync() //returning "test";
this.textBox1.Text = str;
aslında şuna eşittir.
Task.Factory.StartNew(() => { return "test"; } )
            .ContinueWith(task => { this.textBox1.Text = task.Result; },
                            CancellationToken.None,
                            TaskContinuationOptions.None, 
                            TaskScheduler.FromCurrentSynchronizationContext());
async ve StateMachine
async kelimesini gören derleyici
System.Runtime.CompilerServices.AsyncStateMachineAttribute
sınıfını kullanarak bir State Machine oluşturur.

async Event Handler
async Event Handler yazısına taşıdım.

async lambda
async Event Handler yazısına taşıdım.

deadlock
async metodlar eğer yanlış kullanılırsa deadlock'a sebep olabiliyor ancak .Net içindeki sınıflar async/await kullanmadıkları için rahatça kullanılabilir.

async metod içinde await ne işe yarar
await Task'ın bitmesini  beklemek için kullanılır. await ile Task.Factory. Start kullanılabilir.
public async Task FooAsync()
{
    int value = await Task.Factory.StartNew(
                        () => DoSomething(), TaskCreationOptions.LongRunning);
}
veya Task.Run'da kullanılabilir.
public async Task FooAsync()
{
    int value = await Task.Run(() => DoSomething());
}
veya asenkron çalışan bir metod çağrısı yapılır. Şöyle yaparız.
public static async Task <string> job()
{
  ...
  await Task.Delay(2000);
  ...
}
Eğer bunları yapmazsak şöyle bir hata alırız.
Severity Code Description Project File Line Column Warning CS1998 This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. 
Örneğin aşağdaki kod bu hatayı verir.
public async Task<int> GetData() {
        return 1;
}
async metod içinde await ve SyncronizationContext
await çağrılınca altta devam eden kodun kendisini çağıran thread içinde çalışması için SynchronizationContext'i saklar. Şöyle bir kodumuz olsun.
public async Task X()
{
    A();
    await BAsynch();
    C();
}
await çağrısından sonra gelen C() şu hale getirilir.
public Task X()
{
    A();
    return BAsynch().ContinueWith(()=>{ C(); })
}
Dolayısıyla artık Invoke(), BeginInvoke() gibi metodları kullanmaya gerek kalmıyor.

SyncronizationContext Her Thread'de Bulunur mu ?
SynchronizationContext GUI thread'lerinde bulunur ancak konsol thread'lerinde bulunmaz. Dolayısıyla konsolda çalışan bu örnekte farklı sonuçlar görebiliriz.
static  void Main(string[] args)
{
  Console.WriteLine("Main: " + Thread.CurrentThread.ManagedThreadId);//8
  MainAsync(args).Wait();
  Console.WriteLine("Main End: " + Thread.CurrentThread.ManagedThreadId);//8

  Console.ReadKey();
}


static async Task MainAsync(string[] args)
{
  Console.WriteLine("Main Async: " + Thread.CurrentThread.ManagedThreadId);//8

  await thisIsAsync();
}

private static async Task thisIsAsync()
{
  Console.WriteLine("AsyncStart: " + Thread.CurrentThread.ManagedThreadId);//8
  await Task.Delay(1);
  Console.WriteLine("AsyncEnd: " + Thread.CurrentThread.ManagedThreadId);//9

}
async metod içinde await ve Exception
Şöyle yaparız.
async void btncheckPassword_Click(object sender, EventArgs e)
{

  try
  {
    await Task.Run(
      () => 
      {  
        try
        {
          ... //Exception thrown from async method
        }
        catch
        {
          throw new XXX(); //Catch and throw XXX
        }
      }); 

  }
  catch (XXX e) //Code is executed in SynchronizationContext
  {
    ...
  }
}