2013年4月24日 星期三

[ASP.NET] 使用IIS Express開發

常常開發Web系統上遇到在本機執行沒有問題,但是部屬到正式環境就有問題的情況。
此時可以考慮採用IIS Express來做開發與測試,

請參考保哥的文章
ASP.NET 開發人員應使用 IIS Express 進行開發與測試

到專案屬性裡面,將[Web]頁籤裡面的[伺服器]設定為使用IIS Express偵錯



點選[建立虛擬目錄]按鈕後,相關Site設定便會寫入到預設的Config檔:
C:\Users\[使用者名稱]\Documents\IISExpress\config\applicationhost.config

<Site></Site> 標籤就會多出一組開發中 Site的設定,例如


<site name="WebApplication1" id="3">
                <application path="/" applicationPool="Clr4IntegratedAppPool">
                    <virtualDirectory path="/" physicalPath="D:\WORK\CODE\Visual Studio 2010\Projects\WebApplication1" />
                </application>
                <bindings>
                    <binding protocol="http" bindingInformation="*:4863:localhost" />
                </bindings>
            </site>



打開Command,先指到IIS Express資料夾路徑 (預設  C:\Program Files (x86)\IIS Express)
再打入  iisexpress.exe /site:[Site名稱]
此例是  iisexpress.exe /site:WebApplication1

Command就會出現以下訊息,表示已經啟動IIS Express ...

C:\Program Files (x86)\IIS Express>iisexpress.exe /site:WebApplication1
Starting IIS Express ...
Successfully registered URL "http://localhost:4863/" for site "WebApplication1"
application "/"
Registration completed for site "WebApplication1"
IIS Express is running.
Enter 'Q' to stop IIS Express



打開瀏覽器後,打入我們設定好的網址和PORT,就可以看到我們的網站。
也可以在Command即時看到相關Http的訊息。


2013年4月17日 星期三

[C#] 設定程式使用權限


原來程式碼也是可以設定使用權限的~~
雖然實務上不曾用過,不過還滿有趣的。

1.
使用Windows登入腳色
2. 使用自訂使用者

一、                使用Windows登入腳色
l   在需要設定呼叫權限的Class (或方法) 加上以下Attribute
[PrincipalPermission(SecurityAction.Demand, Role = @"Administrator")]
class MyClass
{
  …
}
表示只有登入者為Administrator才有權限。

l   在主程式使用此Class時,需先宣告並設定目前識別的方法為Windows登入腳色:
//設定目前執行緒識別的方法:對應Windows登入腳色AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
try
{
  using (MyClass score = new Score())
  {  //
取出所有學生成績
  
}
}
catch (SecurityException ex)
{
  Console.WriteLine(ex.Message);
}

※若登入腳色非Administrator,則會引發SecurityException : 主要使用權限的要求失敗。
[PrincipalPermission]  Attribute只能加在 Class or Method

l   結束

二、                使用自訂使用者
l   MyClass的建構函式(或是要限制的方法)中,先加入以下程式碼判斷目前執行緒的使用腳色是否有權限:
public MyClass()
{

  
try
   
{
        //
設定主體的所需權限的群組/使用者/腳色
       
PrincipalPermission MyPermission = new PrincipalPermission ("Teacher");
        //
判斷權限是否足夠
       
MyPermission.Demand();
       
        //
Iniitial ...
   
}
    catch (Exception)
    { throw; }
  }

若目前執行緒設定的使用者/腳色非 Teacher,則會引發SecurityException : 主要使用權限的要求失敗。

l   在主程式設定目前執行緒的使用者/腳色,再宣告MyClass物件:

//Create a GenericIdentity object with no authentication type specified.
//
設定泛用無權限使用者 : ExamUser
GenericIdentity examIdentity = new GenericIdentity("DefaultUser");

//
目前使用者腳色
String[] users = new String[2] { "Teacher", "Student" };
//String[] users = new String[1] { "Student" };

//
設定泛用的主體(泛用使用者, 目前腳色)
GenericPrincipal examPrincipal = new GenericPrincipal(examIdentity, users);

//
設定目前執行緒的原則
Thread.CurrentPrincipal = examPrincipal;

try
{
     //
使用MyClass
     using (MyClass _myclass = new MyClass())
     {   //…
    
}
 }

當主程式設定的users包含Teacher,則可正常宣告及使用MyClass ,若只設定使用者為Student則會造成權限失敗。
l   結束。

2013年4月12日 星期五

[C#] Task


BY JB

一、Task without return value
二、Task with return value
三、How to cancel a Task ?
四、TaskFactory
五、Reference

一、Task without return value
l   First implement a function returning nothing
/// <summary>
///
Task要做的事
/// </summary>
///
<param name="x"></param>
private void taskJob(int x)
{
      double _sum = 0;
      try
     
{
          for (int i = 0; i < x; i++)
          {
               Console.WriteLine(i.ToString());
               _sum += i;
          }
          Console.WriteLine( "
總值為={0}", _sum.ToString());
          return;
         }
         catch (Exception)
          {
             throw;
          }
     }

l   Define a Task and add the function as a parameter
// 宣告Task 並指定ActionTask
Task _task = new Task(
 () => taskJob(100)
);

l   Run it!
_task.Start();
l   Output result :

97
98
99
總值為=4950

二、Task with return value
l   First implement a function returning something
/// <summary>
///
Task要做的事
/// </summary>
///
<param name="x"></param>
private double taskJob(int x)
{

 
double _sum = 0;
  try
 
{
      for (int i = 0; i < x; i++)
      {
          Console.WriteLine(i.ToString());
          _sum += i;
       }
       return _sum;
    }
    catch (Exception)
    {
      throw;
    }
}

l   Define a Task and add the function as a parameter
// 宣告Task 並指定可Return值的Func Task
Task<double> _task = new Task<double>(
 () => taskJob(100)
);

l   Run it!
//開始執行Task
_task.Start();

l   Get the result from the Task
//取得Task Return 結果
double _rslt = _task.Result;
Console.WriteLine("
總值={0}", _rslt.ToString());

l   Output result :

97
98
99
總值=4950

三、How to cancel a Task ?

l   Use CancellationTokenSource and check IsCancellationRequested during the working of thread.

                             i.                Define a CancellationTokenSource object.
// System.Threading.CancellationToken 發出訊號,表示應該將它取消。
CancellationTokenSource cts = new CancellationTokenSource();

///
定義Token.Register,表示CancellationToken取消時會呼叫的委派
cts.Token.Register(() =>
 {

   
Console.WriteLine("中途結束Task!");
 });


                            ii.                Implement a function and take the CancellationTokenSource object as one of the parameters.

Check the state of IsCancellationRequested in the thread. If the state is “true”, that means the thread should be cancelled.

/// <summary>
///
Task要做的事
/// </summary>
///
<param name="x"></param>
private static bool taskJob(int x, CancellationToken _ct)
{
  try
 
{
      for (int i = 0; i < x; i++)
      {
         if (_ct.IsCancellationRequested == true)
          {
            return false;
          }
          Console.WriteLine(i.ToString());
       }
   return true;
  }
  catch (Exception)
  {
    return false;
  }
}


                        iii.                Define a Task and add the functionCancellationTokenSource object as parameters.
//宣告Task
Task<bool> _task = new Task<bool>(
      () => taskJob(10000, cts.Token), cts.Token  );

                          iv.                Start the task, then cancel it.

//啟動Task
_task.Start();
//
建立當目標 System.Threading.Tasks.Task<TResult> 完成時隨即執行的接續工作。
//_task.ContinueWith(TaskEnded)

Thread.Sleep(1500);
cts.Cancel();


                           v.                Output result :

5738
5739
5740
中途結束Task!


l   Use CancellationTokenSource and cancel the thread by calling ThrowIfCancellationRequested.

                            i.                Define a CancellationTokenSource object.
(The same as the above sample code)

                            ii.                Implement a function and take the CancellationTokenSource object as one of the parameters.

Call the ThrowIfCancellationRequested() to check if the CancellationTokenSource is canceled in the main thread.
If the CancellationTokenSource is cancelled, ThrowIfCancellationRequested() will throw an exception!

/// <summary>
///
Task要做的事
/// </summary>
///
<param name="x"></param>
private static bool taskJob(int x, CancellationToken _ct)
{

 
try
 
{
      for (int i = 0; i < x; i++)
      {
         //
呼叫ThrowIfCancellationRequested判斷是否已經取消Tocken
       
_ct.ThrowIfCancellationRequested();
       
         Console.WriteLine(i.ToString());
       }
       return true;
   }
   catch (Exception)
   {
     return false;
   }
 }



                        iii.                Define a Task and add the functionCancellationTokenSource object as parameters.
(The same as the above sample code)
                         iv.                Start the task, then cancel it.
(The same as the above sample code)

                           v.                Output result :


5368
5369
中途結束Task!


四、TaskFactory

l   Add multi Task to TaskFactoryand start them

Notice that you may what to put the return Task object of calling
taskFactory.StartNew()  into a Task array, which can be used to set the continued work later.

//宣告TaskFactory
TaskFactory taskFactory = new System.Threading.Tasks.TaskFactory();

//加入Task到工廠並啟動
Task[] tasks = new Task[3]
{
  taskFactory.StartNew( () => taskJob(10000, cts.Token)),
  taskFactory.StartNew( () => taskJob(10000, cts.Token)),
  taskFactory.StartNew( () => taskJob(10000, cts.Token))
};


l   Create a continued works when the tasks finish.

 taskFactory.ContinueWhenAll (tasks, TaskEnded, cts.Token);
//
參數 tasks : Task[] 集合
//
參數 TaskEnded : 要接續的工作 (function name)
//
參數 cts.Token : cts CancellationTokenSource 物件

l   Output result :
2581
2582
2583
2049
2050
2051
2052
2053


The number will appear with the switch of threads.

l   Reference
MSDN