You are on page 1of 15

| 

? 
There are two main ways of multi-threading which .NET encourages: starting your own threads with
ThreadStart delegates, and using the ThreadPool class either directly (using
ThreadPool.QueueUserWorkItem) or indirectly using asynchronous methods (such as
Stream.BeginRead, or calling BeginInvoke on any delegate)

Example1:
£ 
using System;
using System.Threading;
public class Test
{
static void Main()
{
Counter foo = new Counter();
ThreadStart job = new ThreadStart(foo.Count);
Thread thread = new Thread(job);
thread.Start();
for (int i=0; i < 5; i++)
{
Console.WriteLine ("Main thread: {0}", i);
Thread.Sleep(1000);
}
}
}
public class Counter
{ public void Count()
{ for (int i=0; i < 10; i++)
{
Console.WriteLine ("Other thread: {0}", i);
Thread.Sleep(500);
}
}
}
Example2:
£ 
using System;
using System.Threading;

public class Test


{
static void Main()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(PrintOut), "Hello");

// Give the callback time to execute - otherwise the app


// may terminate before it is called
Thread.Sleep(1000);
}
static void PrintOut (object parameter)
{



   



| 
Console.WriteLine(parameter);
}
}

Example 3:

à System
à System.Drawing
à System.Threading
à System.Windows.Forms
à System.IO

MainClass

 Main()
 Thrd
Thread
 TStart
New ThreadStart(AddressOf BusyThread)
Thrd = New Thread(TStart)
Thrd.Priority = ThreadPriority.Highest
Thrd.Start()

Console.WriteLine(Thrd.ThreadState.ToString("G"))

Console.WriteLine("Thrd.IsAlive " & Thrd.IsAlive)

àThrd.IsAlive Then
Thrd.Abort()
Thrd.Join()
à

 BusyThread()
While True
'Console.Write("thread ")
While


£


à System
à System.Drawing
à System.Threading
à System.Windows.Forms
à System.IO
MainClass
 Main()
 Thrd
Thread
 TStart
New ThreadStart(AddressOf BusyThread)
Thrd = New Thread(TStart)
Thrd.Priority = ThreadPriority.Highest
Thrd.Start()



   



| 
Console.WriteLine(Thrd.ThreadState.ToString("G"))

 BusyThread()
While True
'Console.Write("thread ")
While

£

?
? 
Boolean( 8 ) Byte( 3 ) Char( 18 ) Data Type Convert( 9 ) Data Type( 2 ) Decimal( 4 ) Double
Format( 1 ) Double( 10 ) Enum( 6 ) float( 4 ) Hex( 1 ) Integer Parser( 2 )
Integer( 13 ) Long( 8 ) Oct( 1 ) SByte( 1 ) Short( 1 ) Single( 3 ) String
Compare( 13 ) String( 51 ) UInteger( 1 ) ULong( 2 ) UShort( 1 )

à System
£MainClass
 Main(ByVal args
String())
 num_desserts&
 satisfaction_quotient#
num_desserts = 100
satisfaction_quotient# = 1.23
 an_integer
Integer = 100
 a_long
Long = 10000000000
 a_double
Double = 1.0
 a_boolean
Boolean = True
 a_date
Date = #12/31/2007#
 i
Long = 123L
 ch
Char = "X"c
 flags
ULong
flags = 100 ' Decimal 100.
flags = &H64 ' Hexadecimal &H64 = 6 * 16 + 4 = 96 + 4 = 100.
flags = &O144 ' Octal &O144 = 1 * 8 * 8 + 4 * 8 + 4 = 64 + 32 + 4 = 100.
Console.WriteLine(flags) ' Decimal.
Console.WriteLine(Hex(flags)) ' Hexadecimal.
Console.WriteLine(Oct(flags)) ' Octal.

£

     
Imports System
Imports System.IO

Class Test
Public Shared Sub Main()
Try
' Create an instance of StreamReader to read from a file.
' The using statement also closes the StreamReader.
Using sr As New StreamReader("TestFile.txt")
Dim line As String
' Read and display lines from the file until the end of
' the file is reached.



   



| 
Do
line = sr.ReadLine()
If Not (line Is Nothing) Then
Console.WriteLine(line)
End If
Loop Until line Is Nothing
End Using
Catch e As Exception
' Let the user know what went wrong.
Console.WriteLine("The file could not be read:")
Console.WriteLine(e.Message)
End Try
End Sub
End Class
£ 
using System;
using System.IO;
class Test
{
public static void Main()
{
try
{
// Create an instance of StreamReader to read from a file.
// The using statement also closes the StreamReader.
using (StreamReader sr = new StreamReader("TestFile.txt"))
{
String line;
// Read and display lines from the file until the end of
// the file is reached.
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
catch (Exception e)
{
// Let the user know what went wrong.
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}
}
}



Imports System
Imports System.IO
Imports System.Text
Imports System.Collections.Generic



   



| 

Class Program
Public Shared Sub Main(ByVal args As String())
Dim mydocpath As String = _
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
Dim sb As New StringBuilder()
For Each txtName As String _
In Directory.EnumerateFiles(mydocpath, "*.txt")
Using sr As New StreamReader(txtName)
sb.AppendLine(txtName.ToString())
sb.AppendLine("= = = = = =")
sb.Append(sr.ReadToEnd())
sb.AppendLine()
sb.AppendLine()
End Using
Next

Using outfile As New StreamWriter(mydocpath & "\AllTxtFiles.txt")


outfile.Write(sb.ToString())
End Using
End Sub
End Class

£ 
using System;
using System.IO;
using System.Text;
using System.Collections.Generic;

class Program
{ static void Main(string[] args)
{
string mydocpath =
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
StringBuilder sb = new StringBuilder();

foreach (string txtName in Directory.EnumerateFiles(mydocpath,"*.txt"))


{
using (StreamReader sr = new StreamReader(txtName))
{
sb.AppendLine(txtName.ToString());
sb.AppendLine("= = = = = =");
sb.Append(sr.ReadToEnd());
sb.AppendLine();
sb.AppendLine();
}
}
using (StreamWriter outfile =
new StreamWriter(mydocpath + @"\AllTxtFiles.txt"))
{
outfile.Write(sb.ToString());



   



| 
}
}}
2à
£    
The following table lists and describes the main classes used for file I/O.
£  
Provides static methods for creating, moving, and
System.IO.Directory
enumerating through directories and subdirectories.
Provides instance methods for creating, moving, and
System.IO.DirectoryInfo
enumerating through directories and subdirectories.
Provides instance methods for creating, moving, and
System.IO.DriveInfo
enumerating through drives.
Provides static methods for creating, copying,
System.IO.File deleting, moving, and opening files, and aids in the
creation of a FileStream.
Defines constants for read, write, or read/write
System.IO.FileAccess
access to a file.
Provides attributes for files and directories such as
System.IO.FileAttributes
Archive, Hidden, and ReadOnly.
Provides static methods for creating, copying,
System.IO.FileInfo deleting, moving, and opening files, and aids in the
creation of a FileStream.
Controls how a file is opened. This parameter is
specified in many of the constructors for FileStream
System.IO.FileMode
and IsolatedStorageFileStream, and for the Open
methods of File and FileInfo.
Defines constants for controlling the type of access
System.IO.FileShare
other file streams can have to the same file.
Provides methods and properties for processing
System.IO.Path
directory strings.
Controls the access of files and folders by defining
System.Security.Permissions.FileIOPermission Read, Write, Append and PathDiscovery
permissions.
££ 
The following table lists and describes the main classes used to create streams.
£  
Adds a buffering layer to read and write operations on
System.IO.BufferedStream
another stream.
Supports random access to files through its Seek
System.IO.FileStream method. FileStream opens files synchronously by
default but also supports asynchronous operation.
Creates a stream whose backing store is memory,
System.IO.MemoryStream
rather than a file.
Provides the underlying stream of data for network
System.Net.Sockets.NetworkStream
access.
Defines a stream that links data streams to
System.Security.Cryptography.CryptoStream
cryptographic transformations.
£   



   



| 
The following table shows the specific classes used for reading from and writing to files with
streams.
£  
System.IO.BinaryReader Reads encoded strings and primitive data types from a FileStream.
System.IO.BinaryWriter Writes encoded strings and primitive data types to a FileStream.
Reads characters from a FileStream, using CurrentEncoding to convert
characters to and from bytes. StreamReader has a constructor that attempts
System.IO.StreamReader to ascertain the correct CurrentEncoding for a given stream, based on the
presence of a CurrentEncoding-specific preamble, such as a byte order
mark.
Writes characters to a FileStream, using Encoding to convert characters to
System.IO.StreamWriter
bytes.
Reads characters from a String. Output can be either a stream in any
System.IO.StringReader
encoding or a String.
Writes characters to a String. Output can be either a stream in any
System.IO.StringWriter
encoding or a String.


In the .NET Framework, callback functions are just as useful and as pervasive as they are in
unmanaged programming for Windows®. However, the .NET Framework has the added bonus of
providing a type-safe mechanism called . I'll begin my discussion of delegates by
examining how to use one. The code in Figure 1 shows how to declare, create, and use delegates.
Notice the Set class at the top of Figure 1. Pretend that this class contains a set of items that will be
processed individually. When you create a Set object, you pass the number of items it should manage
to its constructor. The constructor then creates an array of Objects and initializes each to an integer
value.
The Set class also defines a public delegate. The delegate indicates the signature of a callback
method. In this example, a Feedback delegate identifies a method that takes three parameters (an
Object, an Int32, and another Int32) and returns void. In a way, a delegate is very much like a C/C++
typedef that represents the address of a function.
In addition, the Set class defines a public method called ProcessItems. This method takes one
parameter, feedback, which is a reference to a Feedback delegate object. ProcessItems iterates
through all the elements of the array, and for each element the callback method (specified by the
feedback variable) is called. This callback method is passed the value of the item being processed,
the item number, and the total number of items in the array. The callback method can process each
item any way it chooses.
Figure 1    

using System;
using System.WinForms; // In beta2: System.Windows.Forms
using System.IO;

class Set {
private Object[] items;

public Set(Int32 numItems) {


items = new Object[numItems];
for (Int32 i = 0; i < numItems; i++)
items[i] = i;
}


   



| 

// Define a Feedback type


// (NOTE: this type is nested within the Set class)
public delegate void Feedback(
Object value, Int32 item, Int32 numItems);

public void ProcessItems(Feedback feedback) {


for (Int32 item = 0; item < items.Length; item++) {
if (feedback != null) {
// If any callbacks are specified, call them
feedback(items[item], item + 1, items.Length);
}
}
}
}

class App {
[STAThreadAttribute]
static void Main() {
StaticCallbacks();
InstanceCallbacks();
}

static void StaticCallbacks() {


// Create a set with 5 items in it
Set setOfItems = new Set(5);

// Process the items, give no feedback


setOfItems.ProcessItems(null);
Console.WriteLine();

// Process the items, give feedback to console


setOfItems.ProcessItems(new Set.Feedback(App.FeedbackToConsole));
Console.WriteLine();

// Process the items, give feedback to a message box


setOfItems.ProcessItems(new Set.Feedback(App.FeedbackToMsgBox));
Console.WriteLine();

// Process the items, give feedback to the


// console AND a message box
Set.Feedback fb = null;
fb += new Set.Feedback(App.FeedbackToConsole);
fb += new Set.Feedback(App.FeedbackToMsgBox);
setOfItems.ProcessItems(fb);
Console.WriteLine();
}

static void FeedbackToConsole(


Object value, Int32 item, Int32 numItems) {
Console.WriteLine("Processing item {0} of {1}: {2}.",



   



| 
item, numItems, value);
}

static void FeedbackToMsgBox(


Object value, Int32 item, Int32 numItems) {
MessageBox.Show(String.Format("Processing item {0} of {1}: {2}.",
item, numItems, value));
}

static void InstanceCallbacks() {


// Create a set with 5 items in it
Set setOfItems = new Set(5);

// Process the items, give feedback to a file


App appobj = new App();
setOfItems.ProcessItems(new Set.Feedback(appobj.FeedbackToFile));
Console.WriteLine();
}

void FeedbackToFile(
Object value, Int32 item, Int32 numItems) {

StreamWriter sw = new StreamWriter("Status", true);


sw.WriteLine("Processing item {0} of {1}: {2}.",
item, numItems, value);
sw.Close();
}
}
V 



   



| 
?  ?   VV
tVVi V 
V liV Vt V   t:V ttV V tV i VV
X  V

VttViVVi tVi  V   tti V VtVtV VV i VVVl lV V
VtV l tV ti V VtVtV
V ttViV itVi V V VtVtVi VitV VV
 iltV VtVi   tV VtVtV VtVV VtiV ttViVi iV
 V VVVVt VtV t lVtV Vti V
VtVi V ttV VVl V
 V VliVtV  VliVMi  tV V  VtV V lVtV V VV
Mi  tVVtVV
X   VV

V tV i ViV  ilV V ii V Vi ti i VtV ti Vt VtVtVV
t i ViVVtV V ltV   tVttV! Vt t Vt V iVtVi V Vii tV V
   V i V  V
V
V" ! V  tlV V!itVt! V t i :VtV
 V tV i V!iViVi V lVt V! V!itVMi  t V V  V#$V Vlt V VtV
l V t i V!iVll !VVt V tVt V t VtV VtVliVV V lV
V t i V itV VtV ll !i V   tVl:VV

VC ti V jtV!iV iVV ti Vt VtVtV

VC  V jtV!iViVVt V%tVV  V

V tR V jtV!iV iVV !  lV V lV tV  tV

V tt V jtV!iV ltVVi tV ttV!itVtV V  VtVV


V
tVV!itV 
V VV i VV ll !:VV
V ti V jtVtliVtV ti V VtVliti V!itVtVtV
V  V
jtV iVi tV%ti V VtV  Vt VtVtVVtV  V t V Vt VV
i lVlVtV  V jtV t VV tR Vt V iVtVtVlt tilVtV
tt V VVVt VillVtV ttV jtV
VtV VVtVi VtV  V
jtV VtV tt VV
V
V
V
V
V
V
V
V
V
V
V
V
V
V
V
V
V
V

     X   VV
?   V

VC ti V jtV tVtV ti Vt VtVtVMi  tV&ilVti V


V
 iVt! VtV VC ti Vl:VtV'lC ti V jtV!iViVi ViillV
t V tVt VMi  tV V  V#$V Vlt V VtVl C ti V jtV!iV V iV



    



| 
connections to a wide range of database types like Microsoft Access and Oracle. The Connection
object contains all of the information required to open a connection to the database.
? £   
The Command object is represented by two corresponding classes: SqlCommand and
OleDbCommand. Command objects are used to execute commands to a database across a data
connection. The Command objects can be used to execute stored procedures on the database, SQL
commands, or return complete tables directly. Command objects provide three methods that are used
to execute commands on the database:
ExecuteNonQuery: Executes commands that have no return values such as INSERT, UPDATE or
DELETE
ExecuteScalar: Returns a single value from a database query
ExecuteReader: Returns a result set by way of a DataReader object

?   
The DataReader object provides a forward-only, read-only, connected stream recordset from a
database. Unlike other components of the Data Provider, DataReader objects cannot be directly
instantiated. Rather, the DataReader is returned as the result of the Command object's ExecuteReader
method. The SqlCommand.ExecuteReader method returns a SqlDataReader object, and the
OleDbCommand.ExecuteReader method returns an OleDbDataReader object. The DataReader can
provide rows of data directly to application logic when you do not need to keep the data cached in
memory. Because only one row is in memory at a time, the DataReader provides the lowest overhead
in terms of system performance but requires the exclusive use of an open Connection object for the
lifetime of the DataReader.
?  
 
The DataAdapter is the class at the core of ADO .NET's disconnected data access. It is essentially the
middleman facilitating all communication between the database and a DataSet. The DataAdapter is
used either to fill a DataTable or DataSet with data from the database with it's Fill method. After the
memory-resident data has been manipulated, the DataAdapter can commit the changes to the
database by calling the Update method. The DataAdapter provides four properties that represent
database commands:
SelectCommand
InsertCommand
DeleteCommand
UpdateCommand
When the Update method is called, changes in the DataSet are copied back to the database and the
appropriate InsertCommand, DeleteCommand, or UpdateCommand is executed
! 
The "Persons" table:
"à #     
 £
1 Hansen Ola Timoteivn 10 Sandnes
2 Svendson Tove Borgvn 23 Sandnes
3 Pettersen Kari Storgt 20 Stavanger
The "Orders" table:
"à   "à
1 77895 3
2 44678 3
3 22456 1
4 24562 1
5 34764 15



   



| 
à ! 
SELECT column_name(s) FROM table_name1 INNER JOIN table_name2 ON
table_name1.column_name=table_name2.column_name
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo FROM Persons INNER JOIN
Orders ON Persons.P_Id=Orders.P_Id ORDER BY Persons.LastName



   



| 
The result-set will look like this:
#       
Hansen Ola 22456
Hansen Ola 24562
Pettersen Kari 77895
Pettersen Kari 44678

# ?! à
SELECT column_name(s) FROM table_name1 LEFT JOIN table_name2 ON
table_name1.column_name=table_name2.column_name

SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo FROM Persons LEFT JOIN


Orders ON Persons.P_Id=Orders.P_Id ORDER BY Persons.LastName

The result-set will look like this:


#    
Hansen Ola 22456
Hansen Ola 24562
Pettersen Kari 77895
Pettersen Kari 44678
Svendson Tove

à?
SELECT column_name(s) FROM table_name1 RIGHT JOIN table_name2 ON
table_name1.column_name=table_name2.column_name

SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo FROM Persons RIGHT JOIN


Orders ON Persons.P_Id=Orders.P_Id ORDER BY Persons.LastName

The result-set will look like this:


#    
Hansen Ola 22456
Hansen Ola 24562
Pettersen Kari 77895
Pettersen Kari 44678
34764


SELECT column_name(s) FROM table_name1 FULL JOIN table_name2 ON
table_name1.column_name=table_name2.column_name

SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo FROM Persons FULL JOIN


Orders ON Persons.P_Id=Orders.P_Id ORDER BY Persons.LastName

The result-set will look like this:


#    
Hansen Ola 22456
Hansen Ola 24562
Pettersen Kari 77895


   



| 
Pettersen Kari 44678
Svendson Tove
34764

$ 
Mobile applications can now be developed to deliver any types of data, to any user, any place in the
world!
Different mobile devices support different programming languages. Some support WAP and WML,
some support HTML or a limited version of HTML, and some support both or a different language.
To support all types of mobile devices, developers must create one different application for each
language.
With .NET Mobile, Microsoft has introduced a new platform for developing mobile applications.
This tutorial is about how to develop applications with an extension to the .NET Framework, called
the Microsoft Mobile Internet Toolkit (MMIT) or simply .NET Mobile.
  
%  
Before you continue you should have a basic understanding of the following:
`V HTML / XHTML
`V XML namespaces
`V ASP .NET
If you want to study these subjects first, find the tutorials on our Home page.

 ?$
.NET Mobile is an extension to Microsoft ASP.NET and the Microsoft's .NET Framework.
.NET Mobile is a set of server-side Forms Controls to build applications for wireless mobile devices.
These controls produce different output for different devices by generating WML, HTML, or
compact HTML.
 à 
The following table shows how the .NET Mobile works:
Mobile Devices
The Internet
Internet Information Services - IIS
The .NET Framework
ASP.NET
.NET Mobile
`V A web client requests a web page
`V The request travels the Internet
`V The request is received by IIS
`V The request is handled by the .NET framework
`V The requested page is compiled by ASP.NET
`V .NET Mobile handles any mobile device requirements
`V The page is returned to the client
&  
To develop mobile applications with .NET Mobile, you must have the following components:
1.V Windows 2000 Professional/Server with IIS 5
2.V All Windows 2000 service packs
3.V The ASP.NET framework
4.V Microsoft Mobile Internet Toolkit (MMIT)
5.V Internet Explorer 5.5 or later
6.V A WAP simulator



   



| 
You will need Windows 2000 to develop .NET applications (IIS 5 (Internet Information Services) is
a part of Windows 2000).
If you want to read more about how to install .NET go to our ASP.NET tutorial.
You also have to install MMIT (.NET Mobile).
Internet Explorer and MMIT can be downloaded from Microsoft MSDN.
?
Developing a mobile web application with ASP.NET is very easy:
1.V Create an ASP.NET page
2.V Include System.Mobile.UI
3.V Add Mobile Controls to the page
<%@ Page
Inherits="System.Web.UI.MobileControls.MobilePage" %>
<%@ Register
TagPrefix="mob"
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>

<mob:Form runat="server">
<mob:Label runat="server">Hello Spiro Solution</mob:Label>
</mob:Form>