Tuesday, December 8, 2009

Automate a process with sqlite3.exe command line tool

Create a separate text file containing all the commands you would normally type into the sqlite3 shell app:

CREATE TABLE log_entry ( );
.separator "\t"
.import /path/to/logfile.log log_entry

Save it as, say, impscript.sql.

Create a batch file which calls the sqlite3 shell with that script:

sqlite3.exe yourdatabase.db < /path/to/impscript.sql

Call the batch file.

Monday, November 16, 2009

SSIS Execute SQL Task and RaisError

If you want to use sp to call an exe program, many ppl reported the raiserror function cannot manually fail a SSIS package step. The problem is we should set the raiserror function parameter severity to be 11 above (11-16). (RAISERROR with an error code of 11 (which is a level SSIS should recognize) ), here is the link I found: http://ulrichandhelvas.wordpress.com/2007/04/04/ssis-ole-db-connection-managers-no-errors-allowed/.

The situation is if you have an exe program, and you want to write a sp to call the exe, when include the sp in your SSIS, if the exe exit code is not 0, the SSIS step will also fail.

I wrote an sp:

CREATE PROCEDURE usp_MyProc

AS
BEGIN
SET NOCOUNT ON;

DECLARE @SQL AS VARCHAR(800)
DECLARE @ret INT

BEGIN
SET @SQL = "C:\Mytest\test.exe"
EXEC @ret = myserver.master.dbo.xp_cmdshell @SQL
IF( @ret <> 0)
BEGIN
RAISERROR ('An error occured',11,1)
END
ELSE
BEGIN
Print 'good'
END

END

END


In this case if my test.exe exit 1, my SSIS step will aslo fail.

Thursday, November 12, 2009

Reflection-Call the Method in a Type

Here we want to write code equivallent to:

DateTime d = new DateTime(2008, 5, 1);
Console.WriteLine(d.ToShortDateString());

What we do is:

Firstly, we must create an instance of the DateTime object, which
requires you to create an instance of ConstructorInfo and then call the ConstructorInfo to Invoke method.

Type t = typeof(DateTime);
//Create a Type object
ConstructorInfo ci = t.GetConstructor(new Type[] { typeof(int), typeof(int),
typeof(int) });
//Type.GetConstructor requires a Type array,
Object d = ci.Invoke(new Object[] { 2008, 5, 1 });
//ConstructorInfo.Invoke requires an Object array.

Next, to call DateTime.ToShortDateString, we
must create an instance of MethodInfo representing the method and then
call MethodInfo.Invoke.

MethodInfo dToShortDateString = t.GetMethod("ToShortDateString");
Console.WriteLine((string)dToShortDateString.Invoke(d, null));

Reflection Related-Use BindingFlags to retrieve memebers

Type t = typeof(Console);
MemberInfo[] mi = t.GetMembers(
BindingFlags.NonPublic | BindingFlags.Static);
foreach (MemberInfo m in mi)
{
Console.WriteLine("{0}: {1}", m.Name, m.MemberType);
}

Tuesday, November 10, 2009

Example of using Reflection to get Constructor and Methods

We can use Assembly.Load, Assembly.LoadFile, Assembly.LoadFrom to load the assembly, and Assembly.GetType to create a Type object.

Here we just add a class, example see http://www.codersource.net/csharp_tutorial_reflection.html.

We use this example code:

public class TestDataType
{

public TestDataType()
{
counter = 1;
}

public TestDataType(int c)
{
counter = c;
}

private int counter;

public int Inc()
{
return counter++;
}
public int Dec()
{
return counter--;
}

}


In the Main class, add System.Reflection namespace. And we can use Type object's GetConstructs, GetMethods methods to get the information out.

The code is like:

TestDataType testObject = new TestDataType(15);
Type objectType = testObject.GetType();

ConstructorInfo[] info = objectType.GetConstructors();
MethodInfo[] methods = objectType.GetMethods();
foreach (ConstructInfo ci in info){....}
foreach (MethodInfo mi in methods){....}

...

Notice that, for the constructor, we get:
Void .ctor()
Void .ctor(Int32)
This is what we constructed.

For the methods, beside the one we constructed,
Int32 Inc()
Int32 Dec()
There are some implict Method, such as
System.ToString()
Equal()
GetHashCode()
We can see from ILDasm as well.

Monday, October 26, 2009

Interoperating with Unmanaged Code Example-Create a Wrapper Class

To create a wrapper class, declare DLL functions within a class. Then define a static
method for each DLL function you want to call.

For example:


using System;
using System.Runtime.InteropServices;
class Win32MessageBox
{
[DllImport("user32.dll")]
private static extern int MessageBox(IntPtr hWnd, String text,
String caption, uint type);
public static void Show(string message, string caption)
{
MessageBox(new IntPtr(0), message, caption, 0);
}
}

class Program
{
static void Main(string[] args)
{
Win32MessageBox.Show("Hello, world!", "My box");
}
}

Interoperating with Unmanaged Code Example-Using Delegate to Call Back Functions in Managed Code

We know that to call an unmanaged function in a COM object, We need to do:
1. Add DllImportAttribute
2. Create a prototype method for the COM function

like:
using System.Runtime.InteropServices;
[DllImport("user32.dll")]
public static extern int MessageBox(int hWnd, String text,
String caption, uint type);


But when the unmanaged function has long pointer parameter?

Here is an example easy to be found in msdn:

using System;
using System.Runtime.InteropServices;

public delegate bool CallBack(int hwnd, int lParam);

public class EnumReportApp {

[DllImport("user32")]
public static extern int EnumWindows(CallBack x, int y);

public static void Main()
{
CallBack myCallBack = new CallBack(EnumReportApp.Report);
EnumWindows(myCallBack, 0);
}

public static bool Report(int hwnd, int lParam) {
Console.Write("Window handle is ");
Console.WriteLine(hwnd);
return true;
}
}


The COM Fuction BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam), notice that if the argument is begin with lp-(long pointer)prefix, this is a function require a call back in COM.

To call a function that requires a callback, follow these steps:
1. Create a method to handle the callback.
2. Create a delegate for the method.
3. Create a prototype for the function, specifying the delegate for the callback
argument.
4. Call the function.

See the references:
http://msdn.microsoft.com/en-us/library/d186xcf0(VS.71).aspx
http://www.pinvoke.net/default.aspx/user32.EnumWindows

Thursday, October 22, 2009

schtasks commadline

Parameter List:
/Create : Creates a new scheduled task.

/Delete : Deletes the scheduled task(s).

/Query : Displays all scheduled tasks.

/Change : Changes the properties of scheduled task.

/Run : Runs the scheduled task immediately.

/End : Stops the currently running scheduled task.

/? Displays this help/usage.

Examples:
SCHTASKS
SCHTASKS /?
SCHTASKS /Run /?
SCHTASKS /End /?
SCHTASKS /Create /?
SCHTASKS /Delete /?
SCHTASKS /Query /?
SCHTASKS /Change /?




SCHTASKS /Create /?

SCHTASKS /Create [/S system [/U username [/P password]]]
[/RU username [/RP password]] /SC schedule [/MO modifier] [/D day]
[/I idletime] /TN taskname /TR taskrun [/ST starttime] [/M months]
[/SD startdate] [/ED enddate]

Description:
Enables an administrator to create scheduled tasks on a local or
remote systems.

Parameter List:
/S system Specifies the remote system to
connect to. If omitted the system
parameter defaults to the local
system.

/U username Specifies the user context under
which the command should execute.

/P password Specifies the password for the given
user context.

/RU username Specifies the user account (user
context) under which the task runs.
For the system account, valid values
are "", "NT AUTHORITY\SYSTEM" or
"SYSTEM".

/RP password Specifies the password for the user.
To prompt for the password, the value
must be either "*" or none.
Password will not effect for the
system account.

/SC schedule Specifies the schedule frequency.
Valid schedule types: MINUTE, HOURLY,
DAILY, WEEKLY, MONTHLY, ONCE,
ONSTART, ONLOGON, ONIDLE.

/MO modifier Refines the schedule type to allow
finer control over schedule
recurrence. Valid values are listed
in the "Modifiers" section below.

/D days Specifies the day of the week to run
the task. Valid values: MON, TUE,
WED, THU, FRI, SAT, SUN and for
MONTHLY schedules 1 - 31 (days of the
month).

/M months Specifies month(s) of the year.
Defaults to the first day of the
month. Valid values: JAN, FEB, MAR,
APR, MAY, JUN, JUL, AUG, SEP, OCT,
NOV, DEC.

/I idletime Specifies the amount of idle time to
wait before running a scheduled
ONIDLE task.
Valid range: 1 - 999 minutes.

/TN taskname Specifies a name which uniquely
identifies this scheduled task.

/TR taskrun Specifies the path and file name of
the program to be run by this
scheduled task.
Example: C:\windows\system32\calc.exe

/ST starttime Specifies the time to run the task.
The time format is HH:MM:SS (24 hour
time) for example, 14:30:00 for
2:30 PM.

/SD startdate Specifies the first date on which the
task runs. The format is
"mm/dd/yyyy".

/ED enddate Specifies the last date when the task
should run. The format is
"mm/dd/yyyy".

/? Displays this help/usage.

Modifiers: Valid values for the /MO switch per schedule type:
MINUTE: 1 - 1439 minutes.
HOURLY: 1 - 23 hours.
DAILY: 1 - 365 days.
WEEKLY: weeks 1 - 52.
ONCE: No modifiers.
ONSTART: No modifiers.
ONLOGON: No modifiers.
ONIDLE: No modifiers.
MONTHLY: 1 - 12, or
FIRST, SECOND, THIRD, FOURTH, LAST, LASTDAY.

Examples:
SCHTASKS /Create /S system /U user /P password /RU runasuser
/RP runaspassword /SC HOURLY /TN rtest1 /TR notepad
SCHTASKS /Create /S system /U domain\user /P password /SC MINUTE
/MO 5 /TN rtest2 /TR calc.exe /ST 12:00:00
/SD 10/20/2001 /ED 10/20/2001 /RU runasuser /RP
SCHTASKS /Create /SC MONTHLY /MO first /D SUN /TN game
/TR c:\windows\system32\freecell
SCHTASKS /Create /S system /U user /P password /RU runasuser
/RP runaspassword /SC WEEKLY /TN test1 /TR notepad.exe
SCHTASKS /Create /S system /U domain\user /P password /SC MINUTE
/MO 5 /TN test2 /TR c:\windows\system32\notepad.exe
/ST 18:30:00 /RU runasuser /RP *
SCHTASKS /Create /SC MONTHLY /MO first /D SUN /TN cell
/TR c:\windows\system32\freecell /RU runasuser





SCHTASKS /delete /?

SCHTASKS /Delete [/S system [/U username [/P password]]] /TN taskname
[/F]

Description:
Deletes one or more scheduled tasks.

Parameter List:
/S system Specifies the remote system to connect to.

/U username Specifies the user context under
which the command should execute.

/P password Specifies the password for the given
user context.

/TN taskname Specifies the name of the scheduled task to
delete. Wildcard "*" may be used to delete
all tasks.

/F (Force) Deletes the task and suppresses
warnings if the specified task is currently
running.

/? Displays this help/usage.

Examples:
SCHTASKS /Delete /TN * /F
SCHTASKS /Delete /TN "Backup and Restore"
SCHTASKS /Delete /S system /U user /P password /TN "Start Restore"
SCHTASKS /Delete /S system /U user /P password /TN "Start Backup" /F








SCHTASKS /query /?

SCHTASKS /Query [/S system [/U username [/P password]]] [/FO format]
[/NH] [/V] [/?]

Description:
Enables an administrator to display the scheduled tasks on the
local or remote system.

Parameter List:
/S system Specifies the remote system to connect to.

/U username Specifies the user context under
which the command should execute.

/P password Specifies the password for the given
user context.

/FO format Specifies the output format to be
displayed. Valid values: TABLE, LIST, CSV.

/NH Specifies that the column header should not
be displayed in the output.
Valid only for TABLE and CSV formats.

/V Specifies additional output to be
displayed.

/? Displays this help/usage.

Examples:
SCHTASKS /Query
SCHTASKS /Query /?
SCHTASKS /Query /S system /U user /P password
SCHTASKS /Query /FO LIST /V /S system /U user /P password
SCHTASKS /Query /FO TABLE /NH /V






SCHTASKS /change /?

SCHTASKS /Change [/S system [/U username [/P password]]] {[/RU runasuser]
[/RP runaspassword] [/TR taskrun]} /TN taskname

Description:
Changes the program to run, or user account and password used
by a scheduled task.

Parameter List:
/S system Specifies the remote system to connect to.

/U username Specifies the user context under
which the command should execute.

/P password Specifies the password for the given
user context.

/RU username Changes the user name (user context) under
which the scheduled task has to run.
For the system account, valid values are
"", "NT AUTHORITY\SYSTEM" or "SYSTEM".

/RP password Specifies a new password for the existing
user context or the password for a new
user account. Password will not effect for
the system account.

/TR taskrun Specifies a new program that the scheduled
task runs. Type the path and file name of
the program.

/TN taskname Specifies which scheduled task to change.

/? Displays this help/usage.

Examples:
SCHTASKS /Change /RP password /TN "Backup and Restore"
SCHTASKS /Change /TR restore.exe /TN "Start Restore"
SCHTASKS /Change /S system /U user /P password /RU newuser
/TN "Start Backup"






SCHTASKS /Run /?

SCHTASKS /Run [/S system [/U username [/P password]]] /TN taskname

Description:
Runs a scheduled task immediately.

Parameter List:
/S system Specifies the remote system to connect
to.

/U username Specifies the user context under
which the command should execute.

/P password Specifies the password for the given
user context.

/TN taskname Identifies the scheduled task to run.

/? Displays this help/usage.

Examples:
SCHTASKS /Run /?
SCHTASKS /Run /TN "Start Backup"
SCHTASKS /Run /S system /U user /P password /TN "Backup and Restore"








SCHTASKS /End /?

SCHTASKS /End [/S system [/U username [/P password]]] /TN taskname

Description:
Stops a running scheduled task.

Parameter List:
/S system Specifies the remote system to connect
to.

/U username Specifies the user context under
which the command should execute.

/P password Specifies the password for the given
user context.

/TN taskname Specifies the scheduled task to
terminate.

/? Displays this help/usage.

Examples:
SCHTASKS /End /?
SCHTASKS /End /TN "Start Backup"
SCHTASKS /End /S system /U user /P password /TN "Backup and Restore"

Friday, July 31, 2009

Check the login user's windowsprincipal(For example whether role is administrator)

using System;
using System.Security.Principal;


WindowsIdentity wi = WindowsIdentity.GetCurrent();
WindowsPrincipal wp = new WindowsPrincipal(wi);
if (wp.IsInRole(WindowsBuiltInRole.Administrator))
{
//Console.WriteLine("Admin");
Console.WriteLine(WindowsBuiltInRole.Administrator.ToString());
}

Tuesday, July 14, 2009

Understand foreach statement

In order an class support foreach statement, it should support GetEnumerator(), MoveNext(), Reset(), Current() Method.
The interface IEnumerator has the method of MoveNext(), Reset(), Current(), and the interface IEnumerable has the method GetEnumerator().
The ICollection, IList interface are derived from IEnumerable and support GetEnumerator() method.

so,

public class MyClass: ICollection, IEnumerator
{}

MyClass A=new MyClass()

foreach(object a in A)....

So ICollection, IList only will not ensure that your collection class support foreach iteration.

We can write MoveNext(), Reset(), Current() in our custom class to support foreach:

class MyIterator
{
int _count;
public MyIterator(int count)
{
_count=count;
}
public string Current { get { return "Hello World!"; } }
public bool MoveNext()
{
if(_count-- > 0)
return true;
return false;
}
}

Class MyCollection
{
public MyIterator GetEnumerator() { return new MyIterator(3); }
}

class Program
{
static void Main(string[] args)
{
foreach (string value in new MyCollection())
Console.WriteLine(value);
}
}

Tuesday, June 30, 2009

Use of BCP Utility

The syntax is:
bcp {[[database_name.][schema].]{table_name | view_name} | "query"}
{in | out | queryout | format} data_file
[-m max_errors] [-f format_file] [-x] [-e err_file]
[-F first_row] [-L last_row] [-b batch_size]
[-n] [-c] [-N] [-w] [-V (70 | 80 | 90 )]
[-q] [-C { ACP | OEM | RAW | code_page } ] [-t field_term]
[-r row_term] [-i input_file] [-o output_file] [-a packet_size]
[-S server_name[\instance_name]] [-U login_id] [-P password]
[-T] [-v] [-R] [-k] [-E] [-h"hint [,...n]"]


for examle:

Export:

run cmd:

bcp "select * from db.dbo.table where ..." queryout "\\..." -Ssever -Uuser -Ppass -c

or we can also use exec master..xp_cmdshell to run it.

if table use "out" option instead of queryout

bcp

Import:

declare @bcp as varchar(200)

set @bcp = 'bcp DBname.dbo.tablename in \\server\filepath\tmpTestFile.txt -c -t : -r # -Sserver -Ulogin -Ppassword -F2

exec master..xp_cmdshell @bcp

or:

exec master.dbo.xp_cmdshell 'bcp AdventureWorks.dbo.test_import in c:\temp\employee.txt -S localhost\SQLExpress -T -c -t ""'

For Example, we can write C# code:
using System;
using System.Diagnostics;


using (Process p = new Process())
{
p.StartInfo.FileName = "bcp";
p.StartInfo.Arguments = "databasename .dbo.tablename in myoutput.txt -Sservername -Usa -Ppass -c -t| -F2";
p.Start();
p.WaitForExit();
}

//Note -t| is delimeter is pipe, -F2 is import from line 2

We can specify the output txt format when use bcp ... out in command line.
When input to db from a txt file, we can write the format file by ourselves:

For example, we have a pipe delimited txt file with txt format like the following.
(file name is C:\mybcp.txt)

ID|Name|Age|Sex
1|Jerry|30|Male
2|Lina|15|Female
3|Jay|88|Male
4|Eric|30|NoRecord
5|Someone|40|NoRecord

We can write the format file (C:\mybcptest.fmt) use txt pad:


9.0
4
1 SQLCHAR 0 100 "|" 1 ID SQL_Latin1_General_CP1_CI_AS
2 SQLCHAR 0 100 "|" 2 DBColumn1 SQL_Latin1_General_CP1_CI_AS
3 SQLCHAR 0 100 "|" 3 Age SQL_Latin1_General_CP1_CI_AS
4 SQLCHAR 0 100 "\r\n" 4 SourceID SQL_Latin1_General_CP1_CI_AS


Notice the 9.0 is the bcp version, we can use command bcp -v to check the bcp version.
4 means the columns in txt files

After create the format files, we can impot the txt files to database, use command:

bcp mydb.dbo.MyClassmates in C:\mybcp.txt -SMyServer -USa -Ppass -fC:\mybcptest.fmt

Monday, June 22, 2009

Debug and Trace

Calling Trace class executes in both debug and release build type, while using Debug only execute in debug mode.

So the following code in Debug and Release build type has different output:

using System;
using System.Diagnostics;

Debug.Listeners.Add(new ConsoleTraceListener());
Debug.AutoFlush = true;

Debug.WriteLine("This is Debug");
Trace.WriteLine("This is Trace");
Console.WriteLine("This is Console");



In Debug build type, output is:

This is Debug
This is Trace
This is Console

In Release build type, output is

This is Debug
This is Console

Wednesday, June 17, 2009

Reading and Writing Event Log

In my computer, right click manage, we can see the events logs by event viewer. The majory types of the event log are: system, security and application types.

In order an application program writing events to the Event log, the application need to be register as an Evnet Source. We can use Regedit.exe to register manually: locate the registry subkey: HKEY_LOCAL_MACHINE\SYSTEM|CurrentControlSet\Services\Eventlog\Application, right click the Application subkey, and click New and type the event source name.

We can also use EventLog object to register event source, read and write to event logs. Reference the name space, System.Diagnostics, the code can be like:

1. Register Application EventLog Source:

if(!EventLog.SourceExists("My Application"))
EventLog.CreateEventSource("My Application","Application");

or:

if(!EventLog.Exists("My Log"))
EventLog.CreateEventSource("My App","My Log");

2. Log Events
We can use EventLog.WriteEntry() method and specify the message, type, eventID,category, rawData. The code sample like:

EventLog myLog=new EventLog("Application");
//Notice this parameter can also be "System",
//"Security", so we can also read/write
//systme and security logs.
myLog.Source="My Application";
myLog.WriteEntry("Could not connect",EventLogEntryType.Error, 1001,1);

3. Read Events
We can also create EventLog instance and access the EventLog.Entries Collection:
EventLog myLog=new EventLog("Application");
foreach(EventLogEntry entry in myLog.Entries)
Console.WriteLine(entry.Message);

Thursday, May 14, 2009

Use ServiceController to Start or Stop a Service

Reference the System.ServiceProcess.dll first, and use the namespace System.ServiceProcess:

We write the code sample as the following:

using System;
using System.ServiceProcess;

class Program
{
static void Main(string[] args)
{
ServiceController sc = new ServiceController("Server");
string svStatus = sc.Status.ToString();
if (svStatus == "Stopped")
{ sc.Start(); }
if (svStatus == "Running")
{ sc.Stop(); }
}
}

Tuesday, May 5, 2009

Use ThreadPool to Queue Work Items

Example:

using System.Threading;

static void Main(string[] args)
{
WaitCallback callback=new WaitCallback(SomeMethod);
ThreadPool.QueueUserWorkItem(callback, "Hi");
ThreadPool.QueueUserWorkItem(callback, "Good Morning");
ThreadPool.QueueUserWorkItem(callback, "Good Bye");
}

static void SomeMethod(object state)
{
string greetingText=(string)state;
Console.Write(geetingText);
}

The step here is Use WaitCallBack delegate to call SomeMethod() and use ThreadPool static method to queue up serverl calls, parameter/object can be passed.

Wednesday, April 29, 2009

AutoResetEvent and ManualResetEvent

This example is good for analysis:(Example from: http://www.java2s.com/Tutorial/CSharp/0420__Thread/AutoResetEventinaction.htm)

using System;
using System.Threading;

public class MainClass
{
public static AutoResetEvent A = new AutoResetEvent(false);
public static int index = 0;

public static int Main(){
Timer T = new Timer(new TimerCallback(TimerHandler), null, 5000, 10000);

A.WaitOne();
Console.WriteLine("Main Thread event signaled");
T.Dispose();
return 0;
}
public static void TimerHandler(object state)
{
Console.WriteLine("TimerHandler");
if (index == 5)
A.Set();

index++;
Console.WriteLine(index);
}
}

Let's Analysize the above code:
1. public static AutoResetEvent A = new AutoResetEvent(false);
here the boolean parameter for the AutoResetEvent represents the initial state, when it is false, it is set as non-signaled.
2. The System.Threading.Timer use the TimerCallback predefined delegate to call the function TimerHandler(), the second thread is created and run.
3. The main Thread goes to WaitOne() method, and blocked to wait the second thread to signal the main thread to go.
4. The Timer get the second function to be invoke after 5000 miliseconds and run every 10000 miliseconds. See the details of how to use Timer() function.
5. In the second thread when the index goes to 5, it send the signal using Set() method, the main thread is set as non-signaled at the beginning and after second thread use Set() to signal the main thread, the main thread become signaled and proceed to execute.
6. Main Thread and second thread both execute until finished.

About the difference of AutoResetEvent and ManualResetEvent is that AutoResetEvent is like a tollbooth, when a car passes by, it automatically closing before the next on can go through but ManualRest is like a door, need to be closed( use Reset() method). And AutoReset will allow only one single waiting thread to continue while ManualResetEvent allows all the threads which is waiton to continue until you use Reset() to stop.

The following codes give an example:

using System;
using System.Threading;

namespace ManualAutoReset
{
class Program
{
delegate void Executor();

private static XXXResetEvent e= new XXXResetEvent(false);

static void Main(string[] args)
{
new Executor(Teste1).BeginInvoke(null, null);
new Executor(Teste2).BeginInvoke(null, null);
new Executor(Teste3).BeginInvoke(null, null);

Console.WriteLine("Fim");
Console.ReadLine();
}
static void Teste1()
{
Console.WriteLine("Teste1 - Begin");

Thread.Sleep(5000);
e.Set();

Console.WriteLine("Teste1 - End");
}

static void Teste2()
{
Console.WriteLine("Teste2 - Begin");
_resetEvent.WaitOne();
Console.WriteLine("Teste2 - End");
}

static void Teste3()
{
Console.WriteLine("Teste3 - Begin");
_resetEvent.WaitOne();
Console.WriteLine("Teste3 - End");
}
}
}

XXX can be Auto or Manual here. If XXX is set to Manual, both thread2 and thread3 will execute. If XXX is Auto, only one in thread2 and thread3 will continue because when one thread is signaled and execute the ResetEvent object is set to false again.

When create or open a named ResetEvent, we need to use EventWaitHandle.
For example the following code shows how to open or create a named event:

EventWaitHandle myEvent=null;
try
{
myEvent=EventWaitHandle.OpenExisting("MyEvent");
}
catch(WaitHandleCannotBeOpenedException)
{
}

if(myEvent==null)
{
myEvent=new EventWaitHandle(false, EventResetMode.AutoReset, "MyEvent");
}

Tuesday, April 28, 2009

Mutex and Semaphore

The source are blocked between the part of WaitOne() and MutexRelease(). The difference between Mutex and Monitor/Block is a Mutex allows synchronization across AppDomain and process boundaries and is flexible.

Here is an example to use Mutex. If one Console application is still running on the Read() method. When we start a new application, it will write out " another instance of this application already owns...".

using System;
using System.Threading;

static void Main(string[] args)
{
bool ownsMutex;
using (Mutex m = new Mutex(true, "MYMUTEX", out ownsMutex))
//pay attention to the "using" usage here
{
if (ownsMutex)
{
m.WaitOne(1000);
Console.WriteLine("Owned");
Console.Read();
m.ReleaseMutex();
}
else
{
Console.WriteLine("Another instance of this application " +
" already owns the mutex named MutexExample.");
}

/* Notice this is also often written styl:
if (! ownsMutex)
{
Console.WriteLine("Already running");
Console.ReadLine();
return; //exit the application
}
Console.WriteLine("First instance");
// do you app stuff here
// e.g. Application.Run(new Form1());
Console.ReadLine();
ownsMutex.Close();
*/
}

The msdn has an example of guarentee the resources be used by one thread a time:
using System;
using System.Threading;

class Test
{
// Create a new Mutex. The creating thread does not own the
// Mutex.
private static Mutex mut = new Mutex();
private const int numIterations = 1;
private const int numThreads = 3;

static void Main()
{
// Create the threads that will use the protected resource.
for(int i = 0; i < numThreads; i++)
{
Thread myThread = new Thread(new ThreadStart(MyThreadProc));
myThread.Name = String.Format("Thread{0}", i + 1);
myThread.Start();
}

// The main thread exits, but the application continues to
// run until all foreground threads have exited.
}

private static void MyThreadProc()
{
for(int i = 0; i < numIterations; i++)
{
UseResource();
}
}

The Semaphore class is used to throttle usage of some resources. Mutex like a key of a door, when a person use the key and enter a room, when he leaves the room, he give the key to the other person, while Semaphore like a room with some limitation of size.So Mutex is a special Semaphore with capacity 1.

Semaphore theSemaphore=new Semaphore(0,10);
//first parameter is initial counts, and the sencond is the capacity.
When we release the slot, we can use:
theSemaphore.Release(5);

Both Mutex and Semaphore has static method of OpenExisting("Name") to Open an existing Mutex or Semephore.

Wednesday, April 22, 2009

Thread related topic

A. ParameterizedThreadStart delegate

Like the non-parmater ThreadStart delegate:

Thread newThread=new Thread(new ThreadStart(Work));
newThread.Start();
static void Work() {...;}

The ParameterizedThreadStart delegate is used like the following:

Thread newThread=new Thread(new ParameterizedThreadStart(WorkWithParameter));
newThread.Start("Hello");
static void WorkWithParameter(object o)
{
string info=(string)o;
....
}

B.Set Thread Priority

Thread thread1=new Thread(new ThreadStart(Work1));
Thread thread2=new Thread(new ThreadStart(Work2));
//we didn't set thread1 priority, it is set
//as default:System.Threading.ThreadPriority.Normal
thread2.Priority = System.Threading.ThreadPriority.Highest;
thread1.Start();
thread2.Start();
There are 5 Priotity Enumeration: Highest,AboveNormal, Normal, BelowNormal, Lowest

C# Coding Style (4)

Framework-Specific Guidelines

A.Multithreading

1.Use synchronization domains. Avoid manual synchronization, because that often leads to deadlocks and race conditions.

2.Never call outside your synchronization domain.

3.Manage asynchronous call completion on a callback method. Do not wait, poll, or block for completion.

4.Always name your threads:

Thread currentThread = Thread.CurrentThread;string threadName = "Main UI Thread";currentThread.Name = threadName;

The name is traced in the debugger Threads window, making debug sessions more productive.

5.Do not call Suspend( ) or Resume( ) on a thread.

6.Do not call Thread.Sleep( ), except in the following conditions:

6.1 Thread.Sleep(0) is an acceptable optimization technique to force a context switch.

6.2 Thread.Sleep( ) is acceptable in testing or simulation code.

7.Do not call THRead.SpinWait( ).

8.Do not call Thread.Abort( ) to terminate threads. Use a synchronization object instead to signal the thread to terminate.

9.Avoid explicitly setting the thread priority to control execution. You can set the thread priority based on task semantics (such as ThreadPriority.BelowNormal for a screensaver).

10.Do not read the value of the ThreadState property. Use Thread.IsAlive( ) to determine whether the thread is dead or alive.

11.Do not rely on setting the thread type to background thread for application shutdown. Use a watchdog or other monitoring entity to deterministically kill threads.

12.Do not use the thread local storage unless thread affinity is guaranteed.

13.Do not call Thread.MemoryBarrier( ).

14.Never call Thread.Join( ) without checking that you are not joining your own thread:

void WaitForThreadToDie(Thread thread){ Debug.Assert(Thread.CurrentThread.ManagedThreadId != thread.ManagedThreadId); thread.Join( );}

15.Always use the lock( ) statement rather than explicit Monitor manipulation.

16.Always encapsulate the lock( ) statement inside the object it protects:

public class MyClass{ public void DoSomething( ) { lock(this) {...} }}

17.You can use synchronized methods instead of writing the lock( ) statement yourself.

18.Avoid fragmented locking.

19.Avoid using a Monitor to wait or pulse objects. Use manual or auto-reset events instead.

20.Do not use volatile variables. Lock your object or fields instead to guarantee deterministic and thread-safe access. Do not use THRead.VolatileRead( ), Thread.VolatileWrite( ), or the volatile modifier.

21.Avoid increasing the maximum number of threads in the thread pool.

22.Never stack lock( ) statements, because that does not provide atomic locking:

MyClass obj1 = new MyClass( );MyClass obj2 = new MyClass( );MyClass obj3 = new MyClass( );//Do not stack lock statementslock(obj1)lock(obj2)lock(obj3){ obj1.DoSomething( ); obj2.DoSomething( ); obj3.DoSomething( );}

Use WaitHandle.WaitAll( ) instead.


B.Serialization

1.Prefer the binary formatter.

2.Mark serialization event-handling methods as private.

3.Use the generic IGenericFormatter interface.

4.Always mark non-sealed classes as serializable.

5.When implementing IDeserializationCallback on a non-sealed class, make sure to do so in a way that allows subclasses to call the base class implementation of OnDeserialization( ).

6.Always mark unserializable member variables as non-serializable.

7.Always mark delegates on a serialized class as non-serializable fields:

[Serializable]public class MyClass{ [field:NonSerialized] public event EventHandler MyEvent;}


C.Remoting

1.Prefer administrative configuration to programmatic configuration.

2.Always implement IDisposable on single-call objects.

3.Always prefer a TCP channel and a binary format when using remoting, unless a firewall is present.

4.Always provide a null lease for a singleton object:

public class MySingleton : MarshalByRefObject{ public override object InitializeLifetimeService( ) { return null; }}

5.Always provide a sponsor for a client-activated object. The sponsor should return the initial lease time.

6.Always unregister the sponsor on client application shutdown.

7.Always put remote objects in class libraries.

8.Avoid using SoapSuds.exe.

9.Avoid hosting in IIS.

10.Avoid using uni-directional channels.

11.Always load a remoting configuration file in Main( ), even if the file is empty and the application does not use remoting:

static void Main( ){ RemotingConfigurationEx.Configure( ); /* Rest of Main( ) */}

12.Avoid using Activator.GetObject( ) and Activator.CreateInstance( ) for remote object activation. Use new instead.

13.Always register port 0 on the client side, to allow callbacks.

14.Always elevate type filtering to Full on both client and host, to allow callbacks.


D.Security

1.Always demand your own strong name on assemblies and components that are private to the application, but are public (so that only you can use them):

public class PublicKeys{ public const string MyCompany = "1234567894800000940000000602000000240000"+ "52534131000400000100010007D1FA57C4AED9F0"+ "A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C83"+ "4C99921EB23BE79AD9D5DCC1DD9AD23613210290"+ "0B723CF980957FC4E177108FC607774F29E8320E"+ "92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99"+ "285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF"+ "0FC4963D261C8A12436518206DC093344D5AD293";}[StrongNameIdentityPermission(SecurityAction.LinkDemand, PublicKey = PublicKeys.MyCompany)]public class MyClass{...}

2.Apply encryption and security protection on application configuration files.

3.When importing an interop method, assert unmanaged code permission and demand appropriate permission instead:

[DllImport("user32",EntryPoint="MessageBoxA")]private static extern int Show(IntPtr handle,string text,string caption, int msgType);[SecurityPermission(SecurityAction.Assert,UnmanagedCode = true)][UIPermission(SecurityAction.Demand, Window = UIPermissionWindow.SafeTopLevelWindows)]public static void Show(string text,string caption){ Show(IntPtr.Zero,text,caption,0);}

4.Do not suppress unmanaged code access via the SuppressUnmanagedCodeSecurity attribute.

5.Do not use the /unsafe switch of TlbImp.exe. Wrap the RCW in managed code so that you can assert and demand permissions declaratively on the wrapper.

6.On server machines, deploy a code access security policy that grants only Microsoft, ECMA, and self (identified by a strong name) full trust. Code originating from anywhere else is implicitly granted nothing.

7.On client machines, deploy a security policy that grants client application only the permissions to execute, to call back the server, and to potentially display user interface. When not using ClickOnce, client application should be identified by a strong name in the code groups.

8.To counter a luring attack, always refuse at the assembly level all permissions not required to perform the task at hand:

[assembly:UIPermission(SecurityAction.RequestRefuse, Window=UIPermissionWindow.AllWindows)]

9.Always set the principal policy in every Main( ) method to Windows:

public class MyClass{ static void Main( ) { AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); } //other methods}

10.Never assert a permission without demanding a different permission in its place.

C# Coding Style (3)

Project Settings and Project Structure

1.Always build your projects with Warning Level 4

2.Treat warnings as errors in the Release build (note that this is not the default of Visual Studio). Although it is optional, this standard recommends treating warnings as errors in Debug builds as well.

3.Avoid suppressing specific compiler warnings.

4.Always explicitly state your supported runtime versions in the application configuration file:

< ? xml version="1.0" ?>< configuration> < startup> < supportedRuntime version="v2.0.5500.0"/> < supportedRuntime version="v1.1.5000.0"/> < /startup>< /configuration>

5.Avoid explicit custom version redirection and binding to CLR assemblies.

6.Avoid explicit preprocessor definitions (#define). Use the project settings for defining conditional compilation constants.

7.Do not put any logic inside AssemblyInfo.cs.

8.Do not put any assembly attributes in any file other than AssemblyInfo.cs.

9.Populate all fields in AssemblyInfo.cs, such as company name, description, and copyright notice.

10.All assembly references should use relative paths.

11.Disallow cyclic references between assemblies.

12.Avoid multi-module assemblies.

13.Avoid tampering with exception handling using the Exception window (Debug Exceptions).

14.Strive to use uniform version numbers on all assemblies and clients in the same logical application (typically, a solution). Use the SolutionInfo.cs technique from Chapter 5 to automate.

15.Name your Visual Studio 2005 application configuration file App.config, and include it in the project.

16.Modify the Visual Studio 2005 default project structure to your project's standard layout, and apply a uniform structure for project folders and files.

17.A release build should contain debug symbols

18.Always sign your assemblies, including the client applications.

19.Use password-protected keys.

C# Coding Style (2)

Coding Practices

1.Avoid putting multiple classes in a single file.

2.A single file should contribute types to only a single namespace. Avoid having multiple namespaces in the same file.

3.Avoid files with more than 500 lines (excluding machine-generated code).

4.Avoid methods with more than 25 lines.

5.Avoid methods with more than five arguments. Use structures for passing multiple arguments.

6.Lines should not exceed 80 characters.

7.Do not manually edit any machine-generated code.

7.1.If modifying machine-generated code, modify the format and style to match this coding standard.

7.2.Use partial classes whenever possible to factor out the maintained portions.

8.Avoid comments that explain the obvious. Code should be self-explanatory. Good code with readable variable and method names should not require comments.

9.Document only operational assumptions, algorithm insights, and so on.

10.Avoid method-level documentation.

10.1,Use extensive external documentation for API documentation.

10.2.Use method-level comments only as tool tips for other developers.

11.With the exception of zero and one, never hardcode a numeric value; always declare a constant instead.

12. Use the const directive only on natural constants, such as the number of days of the week.

13.Avoid using const on read-only variables. For that, use the readonly directive:

public class MyClass{ public const int DaysInWeek = 7; public readonlyint Number; public MyClass(int someValue) { Number = someValue; }}

14.Assert every assumption. On average, every fifth line is an assertion:

using System.Diagnostics;object GetObject( ){...}object someObject = GetObject( );Debug.Assert(someObject != null);

15.Every line of code should be walked through in a "white box" testing manner.

16.Catch only exceptions for which you have explicit handling.

17.In a catch statement that throws an exception, always throw the original exception (or another exception constructed from the original exception) to maintain the stack location of the original error:

catch(Exception exception){ MessageBox.Show(exception.Message); throw; //Same as throw exception;}

18.Avoid error code as method return values.

19.Avoid defining custom exception classes.

20.When defining custom exceptions:

20.1.Derive the custom exception from Exception.

20.2.Provide custom serialization.

21.Avoid multiple Main( ) methods in a single assembly.

22.Make only the most necessary types public; mark others as internal.

23.Avoid friend assemblies, as they increase interassembly coupling.

24.Avoid code that relies on an assembly running from a particular location.

25.Minimize code in application assemblies (i.e., EXE client assemblies). Use class libraries instead to contain business logic.

26. Avoid providing explicit values for enums:

//Correctpublic enum Color{ Red,Green,Blue}//Avoidpublic enum Color{ Red = 1,Green = 2,Blue = 3}

27.Avoid specifying a type for an enum:

//Avoidpublic enum Color : long{ Red,Green,Blue}

28.Always use a curly brace scope in an if statement, even if it contains a single statement.

29.Avoid using the trinary conditional operator.

30.Avoid function calls in Boolean conditional statements. Assign into local variables and check on them:

bool IsEverythingOK( ){...}//Avoid:if(IsEverythingOK( )){...}//Correct:bool ok = IsEverythingOK( );if(ok){...}

31.Always use zero-based arrays.

32.Always explicitly initialize an array of reference types:

public class MyClass{}const int ArrraySize = 100;MyClass[] array = new MyClass[ArrraySize];for(int index = 0; index < array.Length; index++){ array[index] = new MyClass( );}

33.Do not provide public or protected member variables. Use properties instead.

34.Avoid using the new inheritance qualifier. Use override instead.

35.Always mark public and protected methods as virtual in a non-sealed class.

36.Never use unsafe code, except when using interop.

37.Avoid explicit casting. Use the as operator to defensively cast to a type:

Dog dog = new GermanShepherd( );GermanShepherd shepherd = dog as GermanShepherd;if(shepherd != null){...}

38.Always check a delegate for null before invoking it.

39.Do not provide public event member variables. Use event accessors instead.

40.Avoid defining event-handling delegates. Use GenericEventHandler instead.

41.Avoid raising events explicitly. Use EventsHelper to publish events defensively.

42.Always use interfaces.

43.Classes and interfaces should have at least a 2:1 ratio of methods to properties.

44.Avoid interfaces with one member.

45.Strive to have three to five members per interface.

46.Do not have more than 20 members per interface. The practical limit is probably 12.

47.Avoid events as interface members.

48.When using abstract classes, offer an interface as well.

49.Expose interfaces on class hierarchies.

50.Prefer using explicit interface implementation.

51.Never assume a type supports an interface. Defensively query for that interface:

SomeType obj1;IMyInterface obj2;/* Some code to initialize obj1, then: */obj2 = obj1 as IMyInterface;if(obj2 != null){ obj2.Method1( );}else{ //Handle error in expected interface}

52.Never hardcode strings that will be presented to end users. Use resources instead.

53.Never hardcode strings that might change based on deployment, such as connection strings.

54.Use String.Empty instead of "":

//Avoidstring name = "";//Correctstring name = String.Empty;

55.When building a long string, use StringBuilder, not string.

56.Avoid providing methods on structures.

56.1.Parameterized constructors are encouraged.

56.2.You can overload operators.

57.Always provide a static constructor when providing static member variables.

58.Do not use late-binding invocation when early binding is possible.

59.Use application logging and tracing.

60.Never use goto, except in a switch statement fall-through.

61.Always have a default case in a switch statement that asserts:

int number = SomeMethod( );switch(number){ case 1: Trace.WriteLine("Case 1:"); break; case 2: Trace.WriteLine("Case 2:"); break; default: Debug.Assert(false); break;}

62.Do not use the this reference unless invoking another constructor from within a constructor:

//Example of proper use of 'this'public class MyClass{ public MyClass(string message) {} public MyClass( ) : this("Hello") {}}

63.Do not use the base word to access base class members unless you wish to resolve a conflict with a subclass member of the same name or when invoking a base class constructor:

//Example of proper use of 'base'public class Dog{ public Dog(string name) {} virtual public void Bark(int howLong) {}}public class GermanShepherd : Dog{ public GermanShepherd(string name) : base(name) {} override public void Bark(int howLong) { base.Bark(howLong); }}

64.Do not use GC.AddMemoryPressure( ).

65.Do not rely on HandleCollector.

66.Always run code unchecked by default (for the sake of performance), but explicitly in checked mode for overflow- or underflow-prone operations:

int CalcPower(int number,int power){ int result = 1; for(int count = 1;count <= power;count++) { checked { result *= number; } } return result;}

67.Avoid explicit code exclusion of method calls (#if...#endif). Use conditional methods instead:

public class MyClass{ [Conditional("MySpecialCondition")] public void MyMethod( ) {}}

68.Avoid casting to and from System.Object in code that uses generics. Use constraints or the as operator instead:

class SomeClass{}//Avoid:class MyClass{ void SomeMethod(T t) { object temp = t; SomeClass obj = (SomeClass)temp; }}//Correct:class MyClass where T : SomeClass{ void SomeMethod(T t) { SomeClass obj = t; }}

69.Do not define constraints in generic interfaces. Interface-level constraints can often be replaced by strong typing:

public class Customer{...}//Avoid:public interface IList where T : Customer{...}//Correct:public interface ICustomerList : IList{...}

70.Do not define method-specific constraints in interfaces.

71.If a class or a method offers both generic and non-generic flavors, always prefer using the generics flavor.

72.When implementing a generic interface that derived from an equivalent non-generic interface (such as IEnumerable), use explicit interface implementation on all methods, and implement the non-generic methods by delegating to the generic ones:

class MyCollection : IEnumerable { IEnumerator IEnumerable.GetEnumerator() {...} IEnumerator IEnumerable.GetEnumerator() { IEnumerable enumerable = this; return enumerable.GetEnumerator(); } }

C# Coding Style (1)

From lu yong_chao's blog:

Naming Conventions and Styles

1.Use Pascal casing for type and method names and constants:

public class SomeClass
{
const int DefaultSize = 100;
public SomeMethod( ) {}
}

2.Use camel casing for local variable names and method arguments:

int number;
void MyMethod(int someNumber){}

3.Prefix interface names with I:

interface IMyInterface{..}

4.Prefix private member variables with m_.

5.Suffix custom attribute classes with Attribute.

6.Suffix custom exception classes with Exception.

7.Name methods using verb/object pairs, such as ShowDialog( ).

8.Methods with return values should have names describing the values returned, such as GetObjectState( ).

9.Use descriptive variable names.

9.1.Avoid single-character variable names, such as i or t. Use index or temp instead.

9.2.Avoid using Hungarian notation for public or protected members.

9.3.Avoid abbreviating words (such as num instead of number).

10.Always use C# predefined types, rather than the aliases in the System namespace. For example:

object NOT Object
string NOT String
int NOT Int32

11.With generics, use capital letters for types. Reserve suffixing Type for when dealing with the .NET type Type:

//Correct:public class LinkedList{...}//Avoid:public class LinkedList{...}

12.Use meaningful namespace names, such as the product name or the company name.

13.Avoid fully qualified type names. Use the using statement instead.

14.Avoid putting a using statement inside a namespace.

15.Group all framework namespaces together and put custom or third-party namespaces underneath:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using MyCompany;
using MyControls;

16.Use delegate inference instead of explicit delegate instantiation:

delegate void SomeDelegate( );
public void SomeMethod( ){...}
SomeDelegate someDelegate = SomeMethod;

17.Maintain strict indentation. Do not use tabs or nonstandard indentation, such as one space. Recommended values are three or four spaces.

18.Indent comments at the same level of indentation as the code that you are documenting.

19.All comments should pass spellchecking. Misspelled comments indicate sloppy development.

20.All member variables should be declared at the top, with one line separating them from the properties or methods:

public class MyClass
{
int m_Number;
string m_Name;
public void SomeMethod1( ) {}
public void SomeMethod2( ) {}
}

21.Declare a local variable as close as possible to its first use.

22. A filename should reflect the class it contains.

23.When using partial types and allocating a part per file, name each file after the logical part that part plays. For example:

//In MyClass.cs
public partial class MyClass{...}
//In MyClass.Designer.cs
public partial class MyClass{...}

24.Always place an open curly brace ({) in a new line.

25. With anonymous methods, mimic the code layout of a regular method, aligned with the anonymous delegate declaration (this complies with placing an open curly brace in a new line):

delegate void SomeDelegate(string someString);
//Correct:
public void InvokeMethod( )
{
SomeDelegate someDelegate = delegate(string name)
{
MessageBox.Show(name);
};
someDelegate("Juval");
}

//Avoid
public void InvokeMethod( )
{
SomeDelegate someDelegate = delegate(string name){MessageBox.Show(name);};
someDelegate("Juval");
}

26. Use empty parentheses on parameter-less anonymous methods. Omit the parentheses only if the anonymous method could have been used on any delegate:

delegate void SomeDelegate( );//Correct
SomeDelegate someDelegate1 = delegate( )
{
MessageBox.Show("Hello");
};
//Avoid
SomeDelegate someDelegate1 = delegate { MessageBox.Show("Hello"); };

Get ThreadID and AppDomain Name and AppDomainID

Example as following:

using System;
using Sytem.Threading;

static void Main(string[] args)
{
Thread thread=new Thread(new ThreadStart(SomeMethod));
thread.Start();
}

static void SomeMethod()
{
Console.WriteLine ("Thread {0} started in {1} with AppDomainID={2}",
Thread.CurrentThread.ManagedThreadID.ToString(),
Thread.GetDomain().FriendlyName,
Thread.GetDomainID().ToString());
}

Notice to get the ThreadID, we no longer use AppDomain.GetCurrentThreadId() method. But we use Thread.CurrentThread.ManagedThreadID property. Because the former one does not get a stable ThreadID.

Monday, April 20, 2009

Custom Serialization

You can override the serialization by implementing the ISerializable interface and applying the Serializable attribute to the class.

Implement ISerializable involves implementing the GetObjectData method and a special constructor which is used when the object is deserialized.

When you forget to implement GetObjectData, the error will comes at compile time. But if you forget to implement the special constructor, there will comes a serialization exception at compile time.

In the GetObjectData method, add the variables to be serialized as name/value pairs using the AddValue method,wich internally creates the SerializationEntry structures to store the information.

For example, we want to customer the serialization objects as Capital Letters, and deserialized them as lower letters. We construct the class to be serialized as:

[Serializable]
class MyStringData:ISerializable
{
public string dataItemOne, dataItemTwo;

//This is a non-serialization constructor
public MyStringData() { }

//This constructor is for serialization
private MyStringData(SerializationInfo si, StreamingContext ctx)
{
dataItemOne = si.GetString("First_Item").ToLower();
dataItemTwo = si.GetString("dataItemTwo").ToLower();
}

void ISerializable.GetObjectData(SerializationInfo info, StreamingContext ctx)
{
// Fill up the SerializationInfo object with the formatted data.
info.AddValue("First_Item", dataItemOne.ToUpper());
info.AddValue("dataItemTwo", dataItemTwo.ToUpper());
}

}

Writing the test code as following:
static void Main(string[] args)
{
MyStringData sd = new MyStringData();
sd.dataItemOne = "Some data.";
sd.dataItemTwo = "Some more data";

Stream s = new FileStream("MyData.soap",
FileMode.Create, FileAccess.Write, FileShare.None);

SoapFormatter sf = new SoapFormatter();
sf.Serialize(s, sd);
s.Close();

s = File.OpenRead("MyData.soap");
sd = (MyStringData)sf.Deserialize(s);
Console.WriteLine("Item 1: {0}", sd.dataItemOne);
Console.WriteLine("Item 2: {0}", sd.dataItemTwo);
}

Thursday, April 16, 2009

Sql Sever SMO Programming

Reference of msdn: http://msdn.microsoft.com/en-us/library/ms162129.aspx

Add the dll references below for sql server operation first:
Microsoft.SqlSever.ConnectionInfo.dll
Microsoft.SqlSever.Management.Sdk.Sfc.dll
Microsoft.SqlSever.Smo.dll
Microsoft.SqlSever.SqlEnum.dll

As one of my sql scheduled job has activeX script task and some times failed, we need to check the status of the job. If the job failed, we need to re run the job. So I write below an example to check whether the job need to re run.

using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;

static void Main(string[] args)
{
ServerConnection conn = new ServerConnection(@"myServerInstance", "myUserName", "myPassword");
Server srv = new Server(conn);
JobServer agent = srv.JobServer;
foreach (Job e in agent.Jobs)
{
if (e.Name == "My Job scheduled" && e.CurrentRunStatus.ToString() == "Idle" && e.LastRunOutcome.ToString()=="Failed")
{
e.Start();
}
}

If don't use SMO, we can create views:

SELECT *
FROM OPENQuery(myServer1,'exec msdb.dbo.sp_get_composite_job_info')
Union
SELECT *
FROM OPENQuery(myServer2,'exec msdb.dbo.sp_get_composite_job_info')
...

Then query this view.

Wednesday, April 15, 2009

IDeserializationCallBack Interface

When we don't want to serialize some field, and this field is normally dependent on some other field and for the reason of performance concern, we don't serialize them, we use IDeserialization Interface.


For example:
[Serializable]
class Rectangle: IDeserializationCallBack
{
public decimal length;
public decimal width;
[NonSerialized] public decimal area;

publc Rectangle(decimal _length,decimal width)
{
length=_length;
width=_width;
area=length*width;
}

void IdeserializationCallback.OnDeserilization(Object sender)
{
//after deserialization, calculate the area
area=length*width;
}
}

Each time your class is deserialized, the runtime call the IDeserializationCallback.OnDeserialization method after deserialization is complete.

Here is a quick test code:
new Rectangle(50.00, 20.0).Serialize(@"D:\test.txt");
Rectangle rt=new Rectangle();
rt.Deserialize(@"D:\test.txt");
Console.WriteLine(rt);

Tuesday, April 7, 2009

Regex Examples

code is copied from
/*
Mastering Visual C# .NET
by Jason Price, Mike Gunderloy

Publisher: Sybex;
ISBN: 0782129110
*/

Notice how to use Match, Group, Capture, MatchCollection.


using System;
using System.Text.RegularExpressions;

namespace GroupCapture
{
class Program
{
static void Main(string[] args)
{
// create a string containing area codes and phone numbers
string text =
"(800) 555-1211\n" +
"(212) 555-1212\n" +
"(506) 555-1213\n" +
"(650) 555-1214\n" +
"(888) 555-1215\n";

// create a string containing a regular expression to
// match an area code; this is a group of three numbers within
// parentheses, e.g. (800)
// this group is named "areaCodeGroup"
string areaCodeRegExp = @"(?\(\d\d\d\))";

// create a string containing a regular expression to
// match a phone number; this is a group of seven numbers
// with a hyphen after the first three numbers, e.g. 555-1212
// this group is named "phoneGroup"
string phoneRegExp = @"(?\d\d\d\-\d\d\d\d)";

// create a MatchCollection object to store the matches
MatchCollection myMatchCollection =
Regex.Matches(text, areaCodeRegExp + " " + phoneRegExp);

// use a foreach loop to iterate over the Match objects in
// the MatchCollection object
foreach (Match myMatch in myMatchCollection)
{

// display the "areaCodeGroup" group match directly
Console.WriteLine("Area code = " + myMatch.Groups["areaCodeGroup"]);

// display the "phoneGroup" group match directly
Console.WriteLine("Phone = " + myMatch.Groups["phoneGroup"]);

// use a foreach loop to iterate over the Group objects in
// myMatch.Group
foreach (Group myGroup in myMatch.Groups)
{

// use a foreach loop to iterate over the Capture objects in
// myGroup.Captures
foreach (Capture myCapture in myGroup.Captures)
{
Console.WriteLine("myCapture.Value = " + myCapture.Value);
}

}

}
}
}
}

Another Exmple is you are writing an application to process data contained in a text form.Each file contains information about a single customer.
First Name:Tom
Last Name: Perham
Address: 1 Pine St.
City: Springfield
Zip: 01332

After reading the data into a string variable s:


string p=@"First Name: (?.*$)\n"+
@"Last Name: (?.*$)\n"+
@"Address: (?
.*$)\n"+
@"City: (?.*$)\n"+
@"Zip: (?.*$)\n";
Match m=Regex.Match(s,p,RegexOptions.Mutiline);
string fullName=m.Groups["firstName"]+" "+m.Groups["lastName"];
string zip=m.Groups["zip"].ToString();

Note we need to specify the Mutiline option.

Tuesday, March 24, 2009

Event Handling

Second is that event keyword adds accessor method for the event which are just like properties for the fields. While properties have get and set, event accessors have add and remove.
An event is a message sent by an object to signal the occurence of an action.

EventHandler is a predefined delegate that specifically represents an event handler method for an event that does not generate data.

To respond to an event, we need to do 2 things:

(1) Create a method to respond to the event. It must return void and accept two parameters: and Object and an EventArgs(or a derived class):
(Represents an event with no event data.)

private void button1_Click(object sender, EventArgs e)
{
//Method Code
}

(2) Add the event handler to indicate which method should recieve events:
this.button1.Click+=new System.EventHandler(this.button1_Click);
//Here, Click is the predefined event handler.
//We can also define our own as:
//public event ButtonEventHandler ButtonClick;
//this.button1.ButtonClick +=
//new ButtonEventHandler(button1_Click);

Here Click is a predefined EventHandler. When the event occurs, the method you specified will run.

Note that we can define the data for event, instead of using EventArgs:

public class AlarmEventArgs : EventArgs
{
private readonly bool snoozePressed = false;
private readonly int nrings = 0;
// Constructor.
public AlarmEventArgs(bool snoozePressed, int nrings) {...}
// Properties.
public int NumRings{ get { return nrings;}}
public bool SnoozePressed { get { return snoozePressed;}}
public string AlarmText { get {...}}

}

And also we can write our own the EventHandler:

public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);


The step of raise an event also has the following things:

(1) Create an event memeber:

public event AlarmEventHandler Alarm;

(2) Invoke the delegate within a method when you need to raise the event, as the following code demostrates:

AlarmEventArgs e =new AlarmEventArgs ();
if (Alarm != null)
{
//Invokes the delegates.
Alarm(this, e);
}
}

When we new an event memeber or handler, some people may ask why is it significant to use the keyworkd "event" here. It seems if we don't use key word event, like, public AlarmEventHandler Alarm; it also works, the reasons are below:

(1) Invoke restriction:
You don't want people to set the handler to be null and invoke your hander directly, see the blog here for explanation:
http://blog.voidnish.com/?p=20

(2)Event keyword allows the delegate declaration to be included in an interface specification unlike other fields and delegates which are not allowed.

(3)Event keyword adds accessor method for the event which are just like properties for the fields. While properties have get and set, event accessors have add and remove.

Another thing is that event handler can be built-in generic type:
eg:
EventHandler < MyEventArgs> temp = SampleEvent;
if (temp != null)
temp(null , new MyEventArgs(val));

Use Constraints in Generics

We use where clause to apply a constraints to a generic.

ex

class CompGen where T: IComparable
{
public T t1;
pbulic T t2;

public CompGen(T _t1, T _t2)
{
t1=_t1;
t2=_t2;
}

public T Max()
{
if(t2.CompareTo(t1)<0)
return t1;
else
return t2;

}
}

If we remove the where constraints clause, the compiler will return an error because generic type T does not contain a definition of CompareTo.

Thursday, March 19, 2009

Use Reflection to Dynamic Invoke a Method in a dll

We study a sample code below:

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

class Program
{
static void Main(string[] args)
{
string path = @"C:\WINDOWS\Microsoft.NET\Framework\" +
@"v2.0.50727\System.Web.dll";

// Get the Assembly from the file
Assembly webAssembly = Assembly.LoadFile(path);

// Get the type to the HttpUtility class
Type utilType = webAssembly.GetType("System.Web.HttpUtility");

// Get the static HtmlEncode and HtmlDecode methods
MethodInfo encode = utilType.GetMethod("HtmlEncode",
new Type[] { typeof(string) });
MethodInfo decode = utilType.GetMethod("HtmlDecode",
new Type[] { typeof(string) });
// Create a string to be encoded
string originalString =
"This is Sally & Jack's Anniversary ";
Console.WriteLine(originalString);

// encode it and show the encoded value
string encoded =
(string) encode.Invoke(null, new object[] { originalString });
Console.WriteLine(encoded);

// decode it to make sure it comes back right
string decoded =
(string) decode.Invoke(null, new object[] { encoded });
Console.WriteLine(decoded);
}
}

Notice in case we don't need to specify the object type, we can use the code below:

MethodInfo meth=hastType.GetMethod("Add"); //no type parameters
meth.Invoke(hashTable, new Object[]{"Hello","Hi"}); //use Invoke "Add" method to add the Object {"Hello","Hi"} to the hashTable.

Monday, February 23, 2009

Using Cursors Examples in T Sql

Ex 1.

Declare @FName as nvarchar(50)
Declare @LName as nvarchar(100)
Declare @Email as nvarchar(255)

Declare PersonCursor CURSOR FAST_FORWARD FOR

Select fname, lname, email from Person
where city = 'Phoenix'
order by fname

OPEN PersonCursor
FETCH NEXT FROM PersonCursor
INTO @FName, @LName, @Email

WHILE @@FETCH_STATUS = 0
BEGIN
-- do row specific stuff here
print 'FName: ' + @FName
print 'LName: ' + @LName
print 'Email: ' + @Email

FETCH NEXT FROM PersonCursor
INTO @FName, @LName, @Email
END

CLOSE PersonCursor
DEALLOCATE PersonCursor


About @@FETCH_STATUS
0 The FETCH statement was successful.

-1 The FETCH statement failed or the row was beyond the result set.

-2 The row fetched is missing.


Ex 2.

DECLARE @price money
DECLARE @get_price CURSOR

SET @get_price = CURSOR FOR
SELECT price FROM PriceTable where SysID<100

OPEN @get_price

FETCH NEXT FROM @get_price INTO @price

WHILE (@@FETCH_STATUS = 0)
BEGIN
IF @Price < 20
SELECT 'Under 20'
ELSE
SELECT @Price

FETCH NEXT FROM @get_price INTO @price
END

CLOSE @get_price
DEALLOCATE @get_price

As cursors are very poor performers and often other options make more sense for performance reasons, we should be caution when using cursors.

Thursday, February 5, 2009

About SynchronizationContext

A SynchronizationContext allows a thread to communicate with another thread. In .Net framework, WinForms thread context and WPF thread context provide a customer synchronization. A Windows Forms threading model prefers that any user interface code runs directly on the main "user interface" thread. (Contrast to ASP.NET, whre most work is done inside a thread pool so that asynchronous calls can happen on any thread in that pool).

ex.

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button_Click(object sender, EventArgs e)
{
//get an instance of SynchronizationContext class by calling
//the static Current property of SynchronizationContext class
SynchronizationContext uiContext = SynchronizationContext.Current;
Thread thread = new Thread(Run);
thread.Start(uiContext);
}
private void Run(object state)
{
SynchronizationContext uiContext = state as SynchronizationContext;
//Post or Send method to call some code, Post of Send method takes
//two parameters, a delegate pointing to a method and a state object
uiContext.Post(UpdateUI, "Hi");
}
private void UpdateUI(object state)
{
//state object is a string
string text = state as string;
mListBox.Items.Add(text);
}
}

Send and Post are two possible methods you can marshal code to UI thread. The difference is Send is "Synchronous", calling send will execute the code but block until the executing code complete until returning. Post is "Asynchronous", calling Post is more like fire-and-forget in that it queues up the request and returns immediatedly if possible.

Thursday, January 8, 2009

C# 3.0 Object Initialization Expressions and Anonymous Types

Part 1:

We know for standard object initializer, we have class Customer

public class Customer {
public int Age;
public string Name;
public string Country;
public Customer(string name, int age){
this.Name=name;
this.Age=age;
}
}
we know the above code has defult constructor Customer(){} and none default constructor: Customer(string name, int age){this.Name=name;this.Age=age;}

The standard syntax is:
Customer c1=new Customer();
Customer c2=new Customer("Jack",28);

If we want to set Country but not Age, we need to write the code following:

Customer customer=new Customer();
customer.Name="Mike";
customer.Country="France";

C# 3.0 introduces a shorter form of object initiallizaion syntax:
Customer customer=new Cusomer{Name="Mike",Coutry="France"};

For default constructor,we can aslo have the following syntax:
Customer c3=new Customer(){Name="Mike",Coutry="France"};
nondefault constructor:
Customer c4=new Customer("Paolo",21){Country="Italy"};
The c4 assignment above is equivalent to:
Customer c4=new Customer("Paolo",21);
c4.country="Italy";

******************
Part 2:
C# 3.0 Can have anonymous types:
var c5=new {Name="Mike",Coutry="France"};
This code generates a class under the scenes (you never see it), that looks like as below:
class __Anonymous1
{
public string Name;
public string Country;
}

__Anonymous1 c5=new __Anonymous1()
c5.Name="Mike";
c5.Country="France";

Tuesday, January 6, 2009

Delegate, Ananymous Method and Lamda Expression

I am going to copy this one from msdn, as it has good explanation on Ananymous method and lamda expressions:

The contents below are copied from msdn:

"

In C# 1.0, you created an instance of a delegate by explicitly initializing it with a method that was defined elsewhere in the code. C# 2.0 introduced the concept of anonymous methods as a way to write unnamed inline statement blocks that can be executed in a delegate invocation. C# 3.0 introduces lambda expressions, which are similar in concept to anonymous methods but more expressive and concise. These two features are known collectively as anonymous functions. In general, applications that target version 3.5 and later of the .NET Framework should use lambda expressions.

The following example demonstrates the evolution of delegate creation from C# 1.0 to C# 3.0:

C# Copy Code
class Test
{
delegate void TestDelegate(string s);
static void M(string s)
{
Console.WriteLine(s);
}

static void Main(string[] args)
{
// Original delegate syntax required
// initialization with a named method.
TestDelegate testdelA = new TestDelegate(M);

// C# 2.0: A delegate can be initialized with
// inline code, called an "anonymous method." This
// method takes a string as an input parameter.
TestDelegate testDelB = delegate(string s) { Console.WriteLine(s); };

// C# 3.0. A delegate can be initialized with
// a lambda expression. The lambda also takes a string
// as an input parameter (x). The type of x is inferred by the compiler.
TestDelegate testDelC = (x) => { Console.WriteLine(x); };

// Invoke the delegates.
testdelA("Hello. My name is M and I write lines.");
testDelB("That's nothing. I'm anonymous and ");
testDelC("I'm a famous author.");

// Keep console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Hello. My name is M and I write lines.
That's nothing. I'm anonymous and
I'm a famous author.
Press any key to exit.
*/

"

Notice ananymous type and lamda expressions all return to delegate type:

ex1:

A. Traditional delegate:

class SomeClass
{
delegate void SomeDelegate();
public void InvokeMethod()
{
SomeDelegate del = new SomeDelegate(SomeMethod);
del();
}

void SomeMethod()
{
Console.WriteLine("Hello");
}
}

For the traditional delegate, we should new a delegate and pass the function name as signature to the delegate to call back.

B.Ananymous Method

class SomeClass
{
delegate void SomeDelegate();
public void InvokeMethod()
{
SomeDelegate del = delegate()
{
Console.WriteLine("Hello");
};
del();
}
}

C. Lamda Expression

class SomeClass
{
delegate void SomeDelegate();
public void InvokeMethod()
{
SomeDelegate del = () => Console.WriteLine("Hello") ;
del();
}
}

For Lamda Expression, it has syntax

parameters => expression

And:

(int x) => { return x + 1; } is the same as (int x) => x + 1 ; is the same as x=>x+1;

For the Array or class which impliments IEnumerable interface, it has Where extension method, public static IEnumerable Where(this IEnumerable source, Func predicate); predicate is one kind of delegate, we can also place the lamda expression in Where() method:

ex2:
int[] source = new[] { 3, 8, 4, 6, 1, 7, 9, 2, 4, 8 };



foreach (int i in source.Where(x => x > 5))

Console.WriteLine(i);


ex3
int[] source = new[] { 3, 8, 4, 6, 1, 7, 9, 2, 4, 8 };
foreach (int i in source.Where(

x =>
{

if (x <= 3)

return true;//notice here return true or false

else if (x >= 7)

return true;

return false;

}

))

Console.WriteLine(i);

The lamda expression in Where() method return true or false, because for the predicate delegate, there is definition:

public delegate bool Predicate(
T obj
)
true if obj meets the criteria defined within the method represented by this delegate; otherwise, false.