public class ReadOnlyPoint
{
public int X {get; private set;}
public int Y {get; private set;}
public ReadOnlyPoint(int x, int y){X=x; Y=y;}
}
notice the word "private".
We can also use public int X {get;} //new notes
And the for example there is a class Point, it has the default constructor and a second constructor take the variable x.
public class Point
{
public int X{get;set;}
public int Y{get;set;}
public Point {};
public Point(int x){X=x;}
}
When we initialize this object, we can use the default constructor like:
Point p1=new Point{X=3,Y=4};
or we can use the 2nd constructor:
Point p2=new Point(1){Y=3};
We can also get the intializer nested:
public Class Circle
{
public Point Origin{get;set;}
public int Radius{get;set;}
}
var myCircle=new Circle{Origin=new Point{X=2, Y=4}, Radius=3};
For the Collections or the class which implemented IEnumerable interface.
We can write://this is nothing new
List < Point> pointlst=new List< Point>{new Point{X=2, Y=4},
new Point{X=1,Y=5},
new Point{X=3,Y=7}};
Tuesday, November 30, 2010
Linq to XML for those XML Files with Large file size
There is issue when we create XDocument object using the code:
XDocument mydoc=XDocument.Load("myfile.xml");
When the xml file is with large file size, there will have memory out exception.
This is a notorious issue for XDocument class:
See: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2007/09/08/9803.aspx
http://james.newtonking.com/archive/2007/12/11/linq-to-xml-over-large-documents.aspx
We follow the article, the concept is use
XmlReader xreader=XmlReader.Create("myfile.xml");
And create an IEnumerable type object using XmlReader, and use Linq to query this IEnumerable collection.
The code is:
using System.Xml;
using System.Xml.Linq;
class Program
{
static void Main(string[] args)
{
XNamespace myNS = XNamespace.Get("http://myns.xsd");
IEnumerable myElements = GetElements(@"myfile.xml", "product");
var q = from c in myElements
where (null != c.Element(myNS + "merchantListing").Element(myNS + "merchantProduct").Attribute("mid"))
select new { WebID = c.Attribute("id").Value.ToString() };
foreach (var item in q)
{
Console.WriteLine(item.WebID);
}
}
public static IEnumerable GetElements(string fileuri,string name)
{
using(XmlReader xreader=XmlReader.Create(fileuri))
{
xreader.MoveToContent();
while (xreader.Read())
{
if (xreader.NodeType == XmlNodeType.Element && xreader.Name ==name)
{
XElement element = (XElement)XElement.ReadFrom(xreader);
yield return element;
}
}
xreader.Close();
}
}
}
Here we use Linq to XML.
Of course, we don't necessary to "MUST" use Linq. As XDocument.Decendents("..."), this is IEnumerable type, we can use foreach as well.
XDocument myDoc=XDocument.Load("myfile.xml");
//for large size XML please use XMLReader as my previous post
XElement myel=myDoc.Decendent("product");
foreach(var item in myel)
{
Console.WriteLine(item.Element("id").Value);
}
XDocument mydoc=XDocument.Load("myfile.xml");
When the xml file is with large file size, there will have memory out exception.
This is a notorious issue for XDocument class:
See: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2007/09/08/9803.aspx
http://james.newtonking.com/archive/2007/12/11/linq-to-xml-over-large-documents.aspx
We follow the article, the concept is use
XmlReader xreader=XmlReader.Create("myfile.xml");
And create an IEnumerable
The code is:
using System.Xml;
using System.Xml.Linq;
class Program
{
static void Main(string[] args)
{
XNamespace myNS = XNamespace.Get("http://myns.xsd");
IEnumerable
var q = from c in myElements
where (null != c.Element(myNS + "merchantListing").Element(myNS + "merchantProduct").Attribute("mid"))
select new { WebID = c.Attribute("id").Value.ToString() };
foreach (var item in q)
{
Console.WriteLine(item.WebID);
}
}
public static IEnumerable
{
using(XmlReader xreader=XmlReader.Create(fileuri))
{
xreader.MoveToContent();
while (xreader.Read())
{
if (xreader.NodeType == XmlNodeType.Element && xreader.Name ==name)
{
XElement element = (XElement)XElement.ReadFrom(xreader);
yield return element;
}
}
xreader.Close();
}
}
}
Here we use Linq to XML.
Of course, we don't necessary to "MUST" use Linq. As XDocument.Decendents("..."), this is IEnumerable type, we can use foreach as well.
XDocument myDoc=XDocument.Load("myfile.xml");
//for large size XML please use XMLReader as my previous post
XElement myel=myDoc.Decendent("product");
foreach(var item in myel)
{
Console.WriteLine(item.Element("id").Value);
}
Friday, November 19, 2010
Linq to XML for those XML Files which has namespace in it
For example I have a XML file myfile.xml
< ?xml version="1.0" encoding="utf-8"?>
< Products xmlns="http://mytest.xsd">
< Product id="1">
< name> myProduct < /name>
< /Product>
< /Products>
eg. in xsd file we know id is interger.
When we use Linq to XML to query this file, when dealing with XElement or XDecendents, the parameter should be Namespace+ElementName, The code is like below:
XNamespace myNS = XNamespace.Get("http://mytest.xsd");
XDocument myDoc = XDocument.Load(@"myfile.xml");
var query = from c in myDoc.Descendants(myNS + "product")
select new
{MyID=c.Attribute("id")!=null?c.Attribute("id").ToString():String.Empty,
MyName=c.Element(myNS+"name")!=null?MyName=c.Element(myNS+"name").ToString():String.Empty}
< ?xml version="1.0" encoding="utf-8"?>
< Products xmlns="http://mytest.xsd">
< Product id="1">
< name> myProduct < /name>
< /Product>
< /Products>
eg. in xsd file we know id is interger.
When we use Linq to XML to query this file, when dealing with XElement or XDecendents, the parameter should be Namespace+ElementName, The code is like below:
XNamespace myNS = XNamespace.Get("http://mytest.xsd");
XDocument myDoc = XDocument.Load(@"myfile.xml");
var query = from c in myDoc.Descendants(myNS + "product")
select new
{MyID=c.Attribute("id")!=null?c.Attribute("id").ToString():String.Empty,
MyName=c.Element(myNS+"name")!=null?MyName=c.Element(myNS+"name").ToString():String.Empty}
Thursday, November 18, 2010
Silverlight 4 and WCF RIA service (1)
There are some useful links here which we can follow by:
http://weblogs.asp.net/scottgu/archive/2010/05/17/silverlight-4-tools-for-vs-2010-and-wcf-ria-services-released.aspx
http://www.silverlightshow.net/items/WCF-RIA-Services-Part-1-Getting-Started.aspx
http://www.dotnetscraps.com/dotnetscraps/post/Silverlight-and-NET-RIA-Services-Step-by-Step-6.aspx
http://peterkellner.net/2010/01/20/riaservices-silverlight-4-tutorial-svcc-part1of7-introduction/
In 2008, I begin to use Silverlight 2 and ADO.net data service, see my previous articles in 2008. RIA service is pretty much the same concept, it is a WCF service which can let silverlight client side application doing Data layer manipulation.
And I will also write something based on my study and practice.
One thing that people are now doing the debate about silverlight vs html5 furture. silverlight comparing html5 need to install the plugin and problem with crossplat form and performance issue make it seems not that attractive comparing to the html5. But my personal opinion is not need to worry about this too much:
Silverlight belongs to C#/.net developers, and most .Net developer likes this as it seperate the view with C# code. Especially when introduced the MVVM pattern, this get the C# developer more confortbale in Web development.
Silverlight in many places is like a subset of WPF although they are different projects. For developer, SL and WPF are quite similiar in many places. Even SL is dead(I don't think this happens in years), the SL developer can switch to WPF easily.
The techniques comming along with SL such as RIA Service is also useful in ASP.net applications.
On the other hand, HTML5 is more client side code. As a .Net people, developer may not like HTML that much comparing to SL. Current comparing to SL, html5 doesn't have good developement tools. And it doesn't seperate the present layer to logic layer that good comparing to Silverlight. But this also point out a trend of web developement, for the developers the script languages are also important. If some one who is going to take the MCTS 70-515 web developement exam, this also shows Microsoft trend that JQuery library/ AJAX technology became more important than before for .Net web developers.
Now let take look at Silverlight 4 with WCF RIA service.
http://weblogs.asp.net/scottgu/archive/2010/05/17/silverlight-4-tools-for-vs-2010-and-wcf-ria-services-released.aspx
http://www.silverlightshow.net/items/WCF-RIA-Services-Part-1-Getting-Started.aspx
http://www.dotnetscraps.com/dotnetscraps/post/Silverlight-and-NET-RIA-Services-Step-by-Step-6.aspx
http://peterkellner.net/2010/01/20/riaservices-silverlight-4-tutorial-svcc-part1of7-introduction/
In 2008, I begin to use Silverlight 2 and ADO.net data service, see my previous articles in 2008. RIA service is pretty much the same concept, it is a WCF service which can let silverlight client side application doing Data layer manipulation.
And I will also write something based on my study and practice.
One thing that people are now doing the debate about silverlight vs html5 furture. silverlight comparing html5 need to install the plugin and problem with crossplat form and performance issue make it seems not that attractive comparing to the html5. But my personal opinion is not need to worry about this too much:
Silverlight belongs to C#/.net developers, and most .Net developer likes this as it seperate the view with C# code. Especially when introduced the MVVM pattern, this get the C# developer more confortbale in Web development.
Silverlight in many places is like a subset of WPF although they are different projects. For developer, SL and WPF are quite similiar in many places. Even SL is dead(I don't think this happens in years), the SL developer can switch to WPF easily.
The techniques comming along with SL such as RIA Service is also useful in ASP.net applications.
On the other hand, HTML5 is more client side code. As a .Net people, developer may not like HTML that much comparing to SL. Current comparing to SL, html5 doesn't have good developement tools. And it doesn't seperate the present layer to logic layer that good comparing to Silverlight. But this also point out a trend of web developement, for the developers the script languages are also important. If some one who is going to take the MCTS 70-515 web developement exam, this also shows Microsoft trend that JQuery library/ AJAX technology became more important than before for .Net web developers.
Now let take look at Silverlight 4 with WCF RIA service.
Table Variable in TSql
From Performance angle, Table variable is using less resources than temp table.
Declare @MyTable Table
( Name varchar(100), EmployeeNumb int)
Insert Into @MyTable(Name, EmployeeNumb) Values ('Jerry', 2)
Update @MyTable Set EmployeeNumb=EmployeeNumb*2
Declare @MyTable Table
( Name varchar(100), EmployeeNumb int)
Insert Into @MyTable(Name, EmployeeNumb) Values ('Jerry', 2)
Update @MyTable Set EmployeeNumb=EmployeeNumb*2
Monday, November 15, 2010
C# 4.0 new feature (2) --Optional Parameters and Named Parameters
For example:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Cal(5,b:20,c:30));
Console.WriteLine(Cal(5,20, d:false));
}
private static int Cal(int a, int b = 0, int c = 50, bool d = true)
{
int i = a + b - c;
int j = a - b + c;
if (d == true)
return i;
else
return j;
}
}
result:
-5 //true, 5+20-30
35 //false,5-20+50
Sometimes we need to consider matching rule:
The method is be called will be the fewest parameters and also the type should be matched.
forexample:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Add(5));
Console.WriteLine(Add(5,10));
}
private static int Add(int i)
{
return i+2;
}
private static int Add(int i,int j)
{
return i+j;
}
private static double Add(int i,double j)
{
return i+j+2.0;
}
result:
7
10
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Cal(5,b:20,c:30));
Console.WriteLine(Cal(5,20, d:false));
}
private static int Cal(int a, int b = 0, int c = 50, bool d = true)
{
int i = a + b - c;
int j = a - b + c;
if (d == true)
return i;
else
return j;
}
}
result:
-5 //true, 5+20-30
35 //false,5-20+50
Sometimes we need to consider matching rule:
The method is be called will be the fewest parameters and also the type should be matched.
forexample:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Add(5));
Console.WriteLine(Add(5,10));
}
private static int Add(int i)
{
return i+2;
}
private static int Add(int i,int j)
{
return i+j;
}
private static double Add(int i,double j)
{
return i+j+2.0;
}
result:
7
10
Wednesday, November 10, 2010
Use BackgroundWorker (3)
In this artile, I am going to build a simple application which has a button which is to call the calculuation function in background. A progressbar which will show the background progress status. A cancel button which will cancel the background thread working.
We can build this application use Asp.net web application or Window form application or WPF application. As for asp.net there is no default progressbar control in visual studio tool box, there need us to create custom web control in order to show progressbar. So I am going to test use either Winform or WPF application.
For windows form application there is BackgroundWorker control in tool box, so I am going to demostrate how to use this control.
1. Create a winform application.
2. Drag the progressbar control, buttons. And BackgroundWorker control to the form. Like below:
I. Build Progress Bar showing the background calculation progress
In the code behind, after initialize the component, we set the status bar Min/Max values, and the backgroundworker support progressreport and support cancelling property.
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
progressBar1.Minimum=0;
progressBar1.Maximum=100;
In the designer, right click the Background control in the properties events window:
Double click the DoWork, ProgressChanged, RunWorkerCompleted. See the following picture:
In the code behind create the following code:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
Double click Button1, and generate code:
private void button1_Click(object sender, EventArgs e)
{
}
We add the line of the code to call the background thread working:
backgroundWorker1.RunWorkerAsync();
Let's add the following code in the above backgroundWorker1_DoWork method:
for (int i = 0; i <= 10; i++)
{
backgroundWorker1.ReportProgress(i*10);
Thread.Sleep(500);
}
And the code progressBar1.Value=e.ProgressPercentage; to backgroundWorker1_ProgressChanged. Add the code MessageBox.Show("Congradulations, Calculation Finished!"); to backgroundWorker1_RunWorkerCompleted method.
Now the code behind will be:
public partial class BackgroundWorkerExample : Form
{
public BackgroundWorkerExample()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
progressBar1.Minimum = 0;
progressBar1.Maximum = 100;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 10; i++)
{
backgroundWorker1.ReportProgress(i * 10);
Thread.Sleep(500);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Congradulations, Calculation Finished!");
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
}
When we compile this solution, our application support the status update on the background calculation. After calculation is done, there is a message box jump out saying "Congradulations, Calculation Finished!".
The running result is like the following picture:
II. Let the application support Async Cancellation
Double click the Button2 and create code behind:
private void button2_Click(object sender, EventArgs e)
{
}
Add the code backgroundWorker1.CancelAsync(); in the above block.
Change the code in backgroundWorker1_DoWork block to be:
for (int i = 0; i <= 10; i++)
{
if (backgroundWorker1.CancellationPending == true)
{
MessageBox.Show("Calculation Canceled!");
e.Cancel = true;
return;
}
backgroundWorker1.ReportProgress(i*10);
Thread.Sleep(500);
}
And change the code in backgroundWorker1_RunWorkerCompleted block to be:
if (!(e.Cancelled))
MessageBox.Show("Congradulations, Calculation Finished!");
else
MessageBox.Show("Due to Cancellation, Calculation isn't finished");
Rebuilt our solution, now our project support Async Cancellation. Like the picture below:
You can download my code at:
http://groups.google.com/group/jiezhu0815myfiles/web/WinformBackgroundWorkerReportProgress.rar
We can build this application use Asp.net web application or Window form application or WPF application. As for asp.net there is no default progressbar control in visual studio tool box, there need us to create custom web control in order to show progressbar. So I am going to test use either Winform or WPF application.
For windows form application there is BackgroundWorker control in tool box, so I am going to demostrate how to use this control.
1. Create a winform application.
2. Drag the progressbar control, buttons. And BackgroundWorker control to the form. Like below:
I. Build Progress Bar showing the background calculation progress
In the code behind, after initialize the component, we set the status bar Min/Max values, and the backgroundworker support progressreport and support cancelling property.
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
progressBar1.Minimum=0;
progressBar1.Maximum=100;
In the designer, right click the Background control in the properties events window:
Double click the DoWork, ProgressChanged, RunWorkerCompleted. See the following picture:
In the code behind create the following code:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
Double click Button1, and generate code:
private void button1_Click(object sender, EventArgs e)
{
}
We add the line of the code to call the background thread working:
backgroundWorker1.RunWorkerAsync();
Let's add the following code in the above backgroundWorker1_DoWork method:
for (int i = 0; i <= 10; i++)
{
backgroundWorker1.ReportProgress(i*10);
Thread.Sleep(500);
}
And the code progressBar1.Value=e.ProgressPercentage; to backgroundWorker1_ProgressChanged. Add the code MessageBox.Show("Congradulations, Calculation Finished!"); to backgroundWorker1_RunWorkerCompleted method.
Now the code behind will be:
public partial class BackgroundWorkerExample : Form
{
public BackgroundWorkerExample()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
progressBar1.Minimum = 0;
progressBar1.Maximum = 100;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 10; i++)
{
backgroundWorker1.ReportProgress(i * 10);
Thread.Sleep(500);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Congradulations, Calculation Finished!");
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
}
When we compile this solution, our application support the status update on the background calculation. After calculation is done, there is a message box jump out saying "Congradulations, Calculation Finished!".
The running result is like the following picture:
II. Let the application support Async Cancellation
Double click the Button2 and create code behind:
private void button2_Click(object sender, EventArgs e)
{
}
Add the code backgroundWorker1.CancelAsync(); in the above block.
Change the code in backgroundWorker1_DoWork block to be:
for (int i = 0; i <= 10; i++)
{
if (backgroundWorker1.CancellationPending == true)
{
MessageBox.Show("Calculation Canceled!");
e.Cancel = true;
return;
}
backgroundWorker1.ReportProgress(i*10);
Thread.Sleep(500);
}
And change the code in backgroundWorker1_RunWorkerCompleted block to be:
if (!(e.Cancelled))
MessageBox.Show("Congradulations, Calculation Finished!");
else
MessageBox.Show("Due to Cancellation, Calculation isn't finished");
Rebuilt our solution, now our project support Async Cancellation. Like the picture below:
You can download my code at:
http://groups.google.com/group/jiezhu0815myfiles/web/WinformBackgroundWorkerReportProgress.rar
Monday, November 8, 2010
Use BackgroundWorker (2)
Some of the advantages to use BackgroundWorker include:
1. We can report the background thread working process.
2. We can cancel the background process.
Now let's look into this.
Let's look into some more memebers of BackgroundWorker class:
Event handler:
ProgressChanged: The event occurs when Reportprogress method is called.
Method:
ReportProgress: The method raises the ProgressChanged event.The method has one int type parameter indicating the percentage of progress.(eg. 0-100);
Property:
WorkerReportsProgress: This property indicates whether the BackgroundWorker componet can report updates. Notice we should set this property to be true to report out progress status.
III. Background Thread Working Status Report
Let me write the sample code below:
using System;
using System.Threading;
using System.ComponentModel;
class Program
{
static BackgroundWorker myWorker = new BackgroundWorker();
static void Main(string[] args)
{
myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
myWorker.RunWorkerAsync();
myWorker.WorkerReportsProgress = true;
myWorker.ProgressChanged += new ProgressChangedEventHandler(myWorker_ProgressChanged);
Thread.Sleep(6000);
}
static void myWorker_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
Console.WriteLine(e.ProgressPercentage.ToString()+"% finished.");
}
static void myWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 10; i++)
{
myWorker.ReportProgress(i * 10);
Thread.Sleep(500);
}
}
}
Notice the logic here, each time the ReportProgress method is called, it fires up the ProgressChanged event and pass the value i*10 to ProgressChangedEventArgs's ProgressPercentage property.
The running results shows like:
The code is at: http://groups.google.com/group/jiezhu0815myfiles/web/BackgroundWorkerProgressExample.rar
IV.Cancel Background Thread
Comparing to Threadpool, Backgroundworker provides easy manipulation to cancel the background thread.
Let's look at the following Memebers:
Method:
CancelAsync: This method request the cancellation of a pending background operation.
Property:
WorkerSupportsCancellation: This property indicates whether BackgroundWorker component support asynchronous cancellation. In order to use the CancelAsync method, this property need to be set to true.
CancellationPending: This property indicates whether the application has been requested to cancel the background thread. In method(long run calculation method) called by DoWork eventhandler, we judge whether this property is true. If this property is true, we set the DoworkEventArg e and set its Cancel property to be true and use keyword "return" to cancel the background working.
I wrote the code sample below:
using System;
using System.Threading;
using System.ComponentModel;
class Program
{
static BackgroundWorker myWorker = new BackgroundWorker();
static void Main(string[] args)
{
myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
myWorker.RunWorkerAsync();
Thread.Sleep(3000);
Console.WriteLine("Cancelling Background working...");
myWorker.WorkerSupportsCancellation = true;
myWorker.CancelAsync();
Console.Read();
}
static void myWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 10; i++)
{
Console.WriteLine(i.ToString());
Thread.Sleep(500);
if (myWorker.CancellationPending == true)
{
e.Cancel = true;
Console.WriteLine("Background working cancelled.");
return;
}
}
}
}
The running result is like below:
The code is attached here:
http://groups.google.com/group/jiezhu0815myfiles/web/CancelBackgroundWorkerExample.rar
1. We can report the background thread working process.
2. We can cancel the background process.
Now let's look into this.
Let's look into some more memebers of BackgroundWorker class:
Event handler:
ProgressChanged: The event occurs when Reportprogress method is called.
Method:
ReportProgress: The method raises the ProgressChanged event.The method has one int type parameter indicating the percentage of progress.(eg. 0-100);
Property:
WorkerReportsProgress: This property indicates whether the BackgroundWorker componet can report updates. Notice we should set this property to be true to report out progress status.
III. Background Thread Working Status Report
Let me write the sample code below:
using System;
using System.Threading;
using System.ComponentModel;
class Program
{
static BackgroundWorker myWorker = new BackgroundWorker();
static void Main(string[] args)
{
myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
myWorker.RunWorkerAsync();
myWorker.WorkerReportsProgress = true;
myWorker.ProgressChanged += new ProgressChangedEventHandler(myWorker_ProgressChanged);
Thread.Sleep(6000);
}
static void myWorker_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
Console.WriteLine(e.ProgressPercentage.ToString()+"% finished.");
}
static void myWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 10; i++)
{
myWorker.ReportProgress(i * 10);
Thread.Sleep(500);
}
}
}
Notice the logic here, each time the ReportProgress method is called, it fires up the ProgressChanged event and pass the value i*10 to ProgressChangedEventArgs's ProgressPercentage property.
The running results shows like:
The code is at: http://groups.google.com/group/jiezhu0815myfiles/web/BackgroundWorkerProgressExample.rar
IV.Cancel Background Thread
Comparing to Threadpool, Backgroundworker provides easy manipulation to cancel the background thread.
Let's look at the following Memebers:
Method:
CancelAsync: This method request the cancellation of a pending background operation.
Property:
WorkerSupportsCancellation: This property indicates whether BackgroundWorker component support asynchronous cancellation. In order to use the CancelAsync method, this property need to be set to true.
CancellationPending: This property indicates whether the application has been requested to cancel the background thread. In method(long run calculation method) called by DoWork eventhandler, we judge whether this property is true. If this property is true, we set the DoworkEventArg e and set its Cancel property to be true and use keyword "return" to cancel the background working.
I wrote the code sample below:
using System;
using System.Threading;
using System.ComponentModel;
class Program
{
static BackgroundWorker myWorker = new BackgroundWorker();
static void Main(string[] args)
{
myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
myWorker.RunWorkerAsync();
Thread.Sleep(3000);
Console.WriteLine("Cancelling Background working...");
myWorker.WorkerSupportsCancellation = true;
myWorker.CancelAsync();
Console.Read();
}
static void myWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 10; i++)
{
Console.WriteLine(i.ToString());
Thread.Sleep(500);
if (myWorker.CancellationPending == true)
{
e.Cancel = true;
Console.WriteLine("Background working cancelled.");
return;
}
}
}
}
The running result is like below:
The code is attached here:
http://groups.google.com/group/jiezhu0815myfiles/web/CancelBackgroundWorkerExample.rar
Friday, November 5, 2010
Use BackgroundWorker (1)
There are different ways to create multi-threading tasks such as:
1. Asynchronized Model Programming(AMP), I had an article about this before.
2. Parallel Programming, this is aslo used a lot in my daily work such as do parallel downloading of something, I will write an artile on this sometime later.
3. Threadpool.QueueUserworkItem to call back. Use the Threadpool is a traditional way dealing multi-threads tasks.
4. Use BackgroundWorker.
Let's look at the memebers of a BackgroundWorker first:
Let's first look into two event handler:
DoWork: This event handler will call the code in a seperate thread, and the event is fired by calling RunWorkerAsync method.
RunWorkerCompleted: This event occures when background thread completed or cancelled. Or an exception is raised.
and the method called RunWorkerAsync:
RunWorkerAsync: This method will fire the DoWork event.
We can write a simple code sample like:
using System;
using System.Threading;
using System.ComponentModel;
class Program
{
static BackgroundWorker myWorker = new BackgroundWorker();
static void Main(string[] args)
{
myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
myWorker.RunWorkerAsync();
for (int i = 0; ; i++)
{
Console.WriteLine("Main Thread writes: {0}", i.ToString());
Thread.Sleep(1000);
}
}
static void myWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; ; i++)
{
Console.WriteLine("Background Thread writes: {0}", i.ToString());
Thread.Sleep(500);
}
}
}
The following picture shows the running result:
I. Pass parameters from main thread to background thread:
The parameters can be passed from main thread to background thread through include the parater in RunWorkerAsync method. The parameter will be passed to the DoworkEventArgs in background.
Here we change the code a bit:
using System;
using System.Threading;
using System.ComponentModel;
class Program
{
static BackgroundWorker myWorker = new BackgroundWorker();
static void Main(string[] args)
{
string[] names = new string[2] { "Tom", "Jack" };
myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
myWorker.RunWorkerAsync(names);
for (int i = 0; ; i++)
{
Console.WriteLine("Main Thread writes: {0}", i.ToString());
Thread.Sleep(1000);
}
}
static void myWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; ; i++)
{
Console.WriteLine("Hello, {0}. Background Thread writes: {1}", ((string[])(e.Argument))[0], i.ToString());
Thread.Sleep(500);
}
}
}
In the above code, we pass the array to the background thread and used the array element here, the result is like the following picture.
II. Pass the background thread running result to main thread
The background thread runing result can also be passed to the Result property of the RunWorkerCompletedEventArgs parameter.
We write code example below:
using System;
using System.Threading;
using System.ComponentModel;
class Program
{
static BackgroundWorker myWorker = new BackgroundWorker();
static object completedResult;
static void Main(string[] args)
{
string[] names = new string[2] { "Tom", "Jack" };
myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
myWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(myWorker_RunWorkerCompleted);
myWorker.RunWorkerAsync(names);
for (int i = 0;i<10; i++)
{
Console.WriteLine("Main Thread writes: {0}", i.ToString());
Thread.Sleep(2000);
}
Console.WriteLine("The Calculation result from the background thread is:");
Console.WriteLine(completedResult??completedResult.ToString());
Console.Read();
}
static void myWorker_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("Hello, {0}. Now we begin to calculating...", ((string[])e.Argument)[0]);
e.Result = myCal();
}
static void myWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
completedResult = e.Result;
}
static int myCal()
{
int i = 0;
for (int j = 0; j < 10; j++)
{
i += j;
Thread.Sleep(500);
}
return i;
}
}
The running result is like the following:
The sample code is placed at:
http://groups.google.com/group/jiezhu0815myfiles/web/BackgroundWorkerDemo.rar
1. Asynchronized Model Programming(AMP), I had an article about this before.
2. Parallel Programming, this is aslo used a lot in my daily work such as do parallel downloading of something, I will write an artile on this sometime later.
3. Threadpool.QueueUserworkItem to call back. Use the Threadpool is a traditional way dealing multi-threads tasks.
4. Use BackgroundWorker.
Let's look at the memebers of a BackgroundWorker first:
Let's first look into two event handler:
DoWork: This event handler will call the code in a seperate thread, and the event is fired by calling RunWorkerAsync method.
RunWorkerCompleted: This event occures when background thread completed or cancelled. Or an exception is raised.
and the method called RunWorkerAsync:
RunWorkerAsync: This method will fire the DoWork event.
We can write a simple code sample like:
using System;
using System.Threading;
using System.ComponentModel;
class Program
{
static BackgroundWorker myWorker = new BackgroundWorker();
static void Main(string[] args)
{
myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
myWorker.RunWorkerAsync();
for (int i = 0; ; i++)
{
Console.WriteLine("Main Thread writes: {0}", i.ToString());
Thread.Sleep(1000);
}
}
static void myWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; ; i++)
{
Console.WriteLine("Background Thread writes: {0}", i.ToString());
Thread.Sleep(500);
}
}
}
The following picture shows the running result:
I. Pass parameters from main thread to background thread:
The parameters can be passed from main thread to background thread through include the parater in RunWorkerAsync method. The parameter will be passed to the DoworkEventArgs in background.
Here we change the code a bit:
using System;
using System.Threading;
using System.ComponentModel;
class Program
{
static BackgroundWorker myWorker = new BackgroundWorker();
static void Main(string[] args)
{
string[] names = new string[2] { "Tom", "Jack" };
myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
myWorker.RunWorkerAsync(names);
for (int i = 0; ; i++)
{
Console.WriteLine("Main Thread writes: {0}", i.ToString());
Thread.Sleep(1000);
}
}
static void myWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; ; i++)
{
Console.WriteLine("Hello, {0}. Background Thread writes: {1}", ((string[])(e.Argument))[0], i.ToString());
Thread.Sleep(500);
}
}
}
In the above code, we pass the array to the background thread and used the array element here, the result is like the following picture.
II. Pass the background thread running result to main thread
The background thread runing result can also be passed to the Result property of the RunWorkerCompletedEventArgs parameter.
We write code example below:
using System;
using System.Threading;
using System.ComponentModel;
class Program
{
static BackgroundWorker myWorker = new BackgroundWorker();
static object completedResult;
static void Main(string[] args)
{
string[] names = new string[2] { "Tom", "Jack" };
myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
myWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(myWorker_RunWorkerCompleted);
myWorker.RunWorkerAsync(names);
for (int i = 0;i<10; i++)
{
Console.WriteLine("Main Thread writes: {0}", i.ToString());
Thread.Sleep(2000);
}
Console.WriteLine("The Calculation result from the background thread is:");
Console.WriteLine(completedResult??completedResult.ToString());
Console.Read();
}
static void myWorker_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("Hello, {0}. Now we begin to calculating...", ((string[])e.Argument)[0]);
e.Result = myCal();
}
static void myWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
completedResult = e.Result;
}
static int myCal()
{
int i = 0;
for (int j = 0; j < 10; j++)
{
i += j;
Thread.Sleep(500);
}
return i;
}
}
The running result is like the following:
The sample code is placed at:
http://groups.google.com/group/jiezhu0815myfiles/web/BackgroundWorkerDemo.rar
Subscribe to:
Posts (Atom)