Вы находитесь на странице: 1из 12

1.

BASICS AND INDIVIDUAL TOPICS


1.1. Generating Schema, Class and DataSet from XML
Using xsd.exe
To generate a schema definition file (xsd) from XML file orders.xml:

xsd orders.xml

A file called orders.xsd will be generated.

To generate a class definition from the schema definition:

xsd orders.xsd /classes /language:cs

A file called orders.cs containing a class definition in c# will be generated.

To generate a class definition of a strongly typed DataSet from the schema definition:

xsd orders.xsd /dataset /language:cs

1.2. Asynchronous Programming with Delegates


Delegate is a .NET version of function pointer, which can be used for callback purpose.
Moreover, compiler generates some methods and properties for the delegate, including
methods BeginInvoke and EndInvoke, so that we can call the wrapped method
asynchronously.

Now suppose there is the following time-consuming method that needs to be called
asynchronously:

private int Calc(int input1, int input2, ref string strResult)

System.Threading.Thread.Sleep(new System.TimeSpan(0, 0, 0, 5, 0));

strResult = input1 + " + " + input2 + " = " + (input1 + input2);

return input1 + input2;

The application UI is as follows:


When we press the “Calculate” button, the two integers in the first two textboxes are used
to call method Calc, the returned integer result is put in the third textbox, and a string
representation is passed back through Calc’s ref parameter, and is put in the message
textbox.

The bottom textbox and button has nothing to do with the delegate process and is only
used to check that the UI is not locked before the method returns.

An asynchronous method invoking process would be:

1. Define a delegate type with the same signature as the method to call;

private delegate int CalcDelegate(int input1, int input2, ref string strResult);

2. Define a callback method which will be called when the dispatched thread
finishes the time-consuming method call and returns. The content of the
callback method will be discussed later.

private void CalcCallback(IAsyncResult ar)

...

3. To initiate an asynchronous call, create an instance of the delegate type to wrap


the time-consuming method, and call the delegate’s BeginInvoke method with
all parameters needed by the time-consuming method:

CalcDelegate mDeleg;

private void btnCalc_Click(object sender, System.EventArgs e)


{

mDeleg = new CalcDelegate(Calc);

AsyncCallback callback = new AsyncCallback(CalcCallback);

int input1 = Convert.ToInt16(tbInput1.Text);

int input2 = Convert.ToInt16(tbInput2.Text);

string strResult = null; // dummy parameter

deleg.BeginInvoke(input1, input2, ref strResult, callback, 123456789);

When BeginInvoke is called, a separate thread is dispatched to call the time-


consuming method. The last parameter of BeginInvoke is of type object and
can be any object that the caller method wants to pass to the callback method.
It is simply passed to the thread and passed back to the callback method as the
IAsyncResult.AsyncState property.

4. When the wrapped method returns, the thread will call the callback method
with an IAsyncResult parameter. In the callback method, we are supposed to
acquire a handle to the delegate contained in the IAsyncResult, and call its
EndInvoke to get back the result.

private void CalcCallback(IAsyncResult ar)

// Following line is used when this callback method can not acquire a handle of the
delegate, mDeleg, for

// example, when it is in another class. The AsyncDelegate property was generated by


the compiler together

// with the BeginInvoke and EndInvoke methods.

// CalcDelegate mDeleg = (CalcDelegate)(ar.AsyncDelegate);


string strResult = null;

int iResult = mDeleg.EndInvoke(ref strResult, ar);

tbResult.Text = Convert.ToString(iResult); // the third textbox

tbMsg.Text = strResult; // the message textbox

int i = (int)ar.AsyncState;

MessageBox.Show("The ar.AsyncState is " + i); // will show 123456789

The IAsyncResult object that is passed to the callback method does not contain the result
of the time-consuming method. Instead it contains the identity of the calling method and
a handle to the delegate. This asynchronous process is like a dry cleaning store with a
procedure a bit different from common ones. You call in first, leave a job to be done, and
your address – the callback method. When the job is done, the store contacts you through
the address you left, and provides a job number. You go back to the store with the job
number to pick up the job done. The IAsyncResult object contains this job number. You
have to call the time-consuming method again with this job number to get back the real
result.

To do the invoke in one thread:

CalcDelegate deleg = new CalcDelegate(Calc);

//AsyncCallback callback = new AsyncCallback(CalcCallback);

int input1 = Convert.ToInt16(tbInput1.Text);

int input2 = Convert.ToInt16(tbInput2.Text);

string strResult = null; // dummy parameter

IAsyncResult ar = deleg.BeginInvoke(input1, input2, ref strResult, null, new object());

//deleg.BeginInvoke(input1, input2, ref strResult, callback, new object());

ar.AsyncWaitHandle.WaitOne();
strResult = null;

int iResult = deleg.EndInvoke(ref strResult, ar);

tbResult.Text = Convert.ToString(iResult);

tbMsg.Text = strResult;

Note the following difference:

1. No need to pass a callback to BeginInvoke;

2. UI will freeze while waiting;

3. The same delegate handle is used to call both BeginInvoke and EndInvoke.

1.1. Event
The event architecture offers a mechanism for an event generator to notify an event
consumer that something happened. The event generator does not need to know anything
about the consumer. Instead it publishes a method definition in the form of a delegate,
plus an event handle. When the event happens, the generator will call the unknown event
handling method of the consumer through the event handle. A third party which knows
both the generator and the consumer is responsible to connect the consumer’s event
handling method with the published event handle of the generator.

Example:

// The event and the event args are defined by the event generator.

public class MyEventArgs : EventArgs

private string mstrName;

public MyEventArgs(string strName)

mstrName = strName;
}

public string Name

get { return mstrName; }

set { mstrName = value; }

public delegate void MyEvent(object sender, MyEventArgs e);

public class EventGenerator

public event MyEvent MyEventExposed;

public void GenerateEvent()

if (MyEventExposed != null)

MyEventArgs args = new MyEventArgs("MyEvent");

MyEventExposed(this, args);

else
Console.WriteLine("Event not connected to event consumer!");

public class EventConsumer

public void HandleEvent(object sender, MyEventArgs e)

Console.WriteLine("Event name: \"" + e.Name + "\"");

public class EventConnector

public static void Main (string[] args)

EventConsumer consumer = new EventConsumer();

EventGenerator generator = new EventGenerator();

generator.MyEventExposed += new MyEvent(consumer.HandleEvent);

generator.GenerateEvent();

Console.ReadLine();

}
1.2. Convert Between Objects & byte Array with
BinaryFormatter
In the following example, we create a object of a simple class Car, convert it into a byte
array, and convert it back.

using System;

using System.IO;

using System.Runtime.Serialization.Formatters.Binary;

namespace For_Testing_Simple_Code

[Serializable]

class Car

private string mstrMake;

private string mstrModel;

private int miYear;

private string mstrReg;

public Car(string strMake, string strModel, int iYear, string strReg)

mstrMake = strMake;

mstrModel = strModel;

miYear = iYear;

mstrReg = strReg;
}

override public string ToString()

return mstrMake + ", " + mstrModel + ", " + miYear + ", " + mstrReg;

class Class1

[STAThread]

static void Main(string[] args)

Car car1 = new Car("Toyota", "Camry", 2001, "ABC123");

MemoryStream memStream1 = new MemoryStream();

BinaryFormatter formatter = new BinaryFormatter();

formatter.Serialize(memStream1, car1);

byte [] bytes = memStream1.GetBuffer();

memStream1.Close();

MemoryStream memStream2 = new MemoryStream(bytes);


Car car2 = (Car)formatter.Deserialize(memStream2);

Console.WriteLine(car2.ToString());

Console.ReadLine();

The output is:

Toyota, Camry, 2001, ABC123

1.3. Encrypting and Decrypting with DES Crypto


Service Provider
using System;

using System.IO;

using System.Security.Cryptography;

namespace For_Simple_Test

class Class1

[STAThread]

static void Main(string[] args)

// Both desKey and desIV could be any 8-byte array.

byte [] desKey = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
byte [] desIV = {0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78};

//**** Encryption Process ****

FileStream fsOriginal = new FileStream("Original.txt", FileMode.Open,


FileAccess.Read);

FileStream fsEncrypted = new FileStream("Encrypted.txt",


FileMode.OpenOrCreate, FileAccess.Write);

byte[] buffer = new byte[5000];

DESCryptoServiceProvider des = new DESCryptoServiceProvider();

CryptoStream encryptStream = new CryptoStream(

fsEncrypted,

des.CreateEncryptor(desKey, desIV),

CryptoStreamMode.Write);

//Read from the input file, then encrypt and write to the output file.

int iLenth = fsOriginal.Read(buffer, 0, 5000);

encryptStream.Write(buffer, 0, iLenth);

encryptStream.Close();

fsOriginal.Close();

fsEncrypted.Close();
//**** Decryption Process ****

fsEncrypted = new FileStream("Encrypted.txt", FileMode.Open,


FileAccess.Read);

FileStream fsDecrypted = new FileStream("Decrypted.txt",


FileMode.OpenOrCreate, FileAccess.Write);

CryptoStream decryptStream = new CryptoStream(

fsDecrypted,

des.CreateDecryptor(desKey, desIV),

CryptoStreamMode.Write);

iLenth = fsEncrypted.Read(buffer, 0, 5000);

decryptStream.Write(buffer, 0, iLenth);

decryptStream.Close();

fsEncrypted.Close();

fsDecrypted.Close();

Вам также может понравиться