Aug 2, 2010

Synchronization of Threads

In this series of articles I show a lot of the mechanisms we have in .NET to program Multi Threaded applications and to perform asynchronous operations.
Here are the articles in this series:
Asynchronous Programming in .NET
Synchronizing Threads in .NET
MultiThreading Without The Thread Class

Introduction
 In this article I will show how to synchronize threads.

Thread Local Storage
Lets look at the following example:
---------------------------------------
class A
{
public void f1()
{
Delay = 300;
for (int i=0; i<10; i++)
{
Console.WriteLine("f1: " + Delay);
Thread.Sleep(Delay);
}
}
public void f2()
{
Delay = 500;
for (int i=0; i<10; i++)
{
Console.WriteLine("f2: " + Delay);
Thread.Sleep(Delay);
}
}
public static int Delay = 500;
}
class Class1
{
static void Main(string[] args)
{
A a = new A();
Thread t1 = new Thread(new ThreadStart(a.f1));
Thread t2 = new Thread(new ThreadStart(a.f2));
t1.Start();
t2.Start();
Thread.Sleep(1000);
Console.WriteLine("Main End");
}
}
-------------------------------------------------
Delay is a static member of A. If you will run this you will see that the last thread to change Delay will change it both for f1 and f2. The thing is that both threads share the same member, and the last one to change it wins it all.

What we want really is to have one Delay for the first thread, and another Delay for the second thread. There is a built-in mechanism for that in Win32 called Thread Local Storage, and the way to do it in .NET is by using the [ThreadStatic] attribute before declaring the static member.
[ThreadStatic] public static int Delay = 500;

As you can see we initialized the Delay member with a value. This initialization only applies to the main thread. Each thread must set a value in the entry point method, or the value will be 0.
If you run the program now you will see that each thread has its own delay.

Synchronization Mechanisms
Two threads want to access the same variable, or the same code. Context switches can occur at any time, so if the context switch occur in a critical point, the threads can cause unexpected results. An example could be when a thread tries to decrease a variable by one, so it places it in a register, and at that point a context switch occur, another thread decreases the variable, if a context switch occurs again the variable will be decreased only once instead of twich.

There are declerative ways and coding ways to perform synchronization in .NET.
The WaitHandle class is an abstract class which provides a way to signal other threads. Three classes derive from the WaitHandle class: ManualResetEvent, AutoResetEvent and Mutex.
The AutoResetEvent class involves cases in which we want to make sure that threads will sleep until another thread finishes a task. It has two states: Set and Reset. The Set state is signalling one thread to stop waiting, and then automatically goes back to Reset state. A thread can call the WaitOne method of the AutoResetEvent object, and then it is blocked until someone calls the Set method.
Here is an example.

The ManualResetEvent is similar to AutoResetEvent. When a threads wants to block all other threads it calls the Reset method. If any other thread calls the WaitOne it will be blocked until someone calls the Set method. All the threads will be released, and the state will remain Set, until someone sets the state again to Reset.

The Mutex class is used when we want to protect a resource or a critical code. We call the WaitOne at the beginning of the section, and the ReleaseMutex at the end of the section. If one thread called the WaitOne method, other threads will be blocked on that line until the thread calls the ReleaseMutex class. You should perform the ReleaseMutex operation in the finally clause. For a short and nice example look at MSDN .
In 2005 a Semaphore class was added to the framework. There are also named mutexes, and there is an Access Control List feature.

Race Conditions
The class Interlocked provides methods to perform operations as atomic. This will prevent race conditions between threads on variables. In the 2003 version this class provides Increment, Decrement,Exchange (switches two variables), and CompareExchange. In the 2005 version other features were added.

Using Attributes to Synchronize Classes
A class that derives from ContextBoundObject (such as ServicedComponent) can be assigned with the [Synchronization] attribute. No more than one thread will be able to access the class methods and properties. This will not block static methods and members. This is a very easy but strict mechanism. It is not suitable in many cases, for example when there is a Read and Write method. Only one thread can access the Write method, but few threads can access the Read method. This will not work with this attribute.
The class is in the System.Runtime.Remoting.Contexts namespace.

There is a way to protect a method from getting accessed bymore than one thread. Add the following attribute to the method [MethodImpl(MethodImplOptions.Synchronized)].

Locks
C# has a built-in locking mechanism. The lock is per object, so if you want to prevent two threads from executing critical sections together, they should lock on the same object:
---------------------------------------------

public void f1()
{
lock(x)
{
for (int i=0; i<10; i++)
{
Console.WriteLine("f1: " + i);
Thread.Sleep(300);
}
}
}
public void f2()
{
lock(x)
{
for (int i=0; i<10; i++)
{
Console.WriteLine("f2: " + i);
Thread.Sleep(500);
}
}
}
object x = new object();
--------------------------------------------
Only one method can perform the loop at the same time. The ither thread will have to wait until the lock is freed. You can lock on any type of object.

Behind the scenes .NET uses the class Monitor.
If you want to lock a critical section in the context of the object, you can do lock(this).
This will prevent two threads from accessing the critical section only when accessing the same object.

If you want to lock a section in a static method, you might use lock(typeof(MyClass)) .

A nice class to perform read and write operations is the ReaderWriterLock, which lets aquiring a number of reader locks, and only one writer lock.

Summary
In this article I showed a number of ways to synchronize threads using Locks, Mutex, Manual/AutoResetEvent, and attributes. I also showed how to use the Thread Local Storage.

In the next article I will discuss timers, ThreadPool, and Asynchronous delegates.

Jul 28, 2010

Backgroundworker threads

Backgroundworker threads

The BackgroundWorker class is a component in Windows Forms applications that can be used for task which take some time. Task will be run in a dedicated thread (asynchr). You can drag de background wordker from the compenent tab in the toolbox on to the form.
In a triggered method, create the events if the thread has to be created. Implement 3 events. The work event, the completed event and de progress changed event. This does not trigger the thread, but only implements the functionality
private void InitializeBackgoundWorker()
{
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler( backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler( backgroundWorker1_ProgressChanged);
}
Example implementation DoWork event:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
e.Result = DoLongWork((int)e.Argument, worker, e);
}
The sender is de background worker. The eventargs contain the option for cancelling the operation. The worker object tells abut the status. The user could have choosen to cancel the operation. If the consuming time function is executing. The worker status can be questionned along the way. A user could have choosen the cancel the operation.
if (worker.CancellationPending) { e.Cancel = true; }
With the function backgroundWorker1.CancelAsync(); the thread can be cancelled.With the function backgroundWorker1.RunWorkerAsync(numberToCompute); the thread can be started.

After completing or cancelling the thread the Completed event will be triggered
private void backgroundWorker1_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e) { }
The eventargs contains the result.
e has attribute error. The e.Error can be set in the DoWork event
e has attribute cancelled. The e.Cancelled can be set in the DoWork event
e has attribute result. Also can be set in the DoWork event.
In the DoWork event the progress can be reported. Call worker.ReportProgress(percentComplete);
In the event handler of ProgessChanged read the value:
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
textBoxCompleted.Text = e.ProgressPercentage.ToString() + "% completed";
}

Jul 19, 2010

DevExpress Win Form XGrid Set focus on editied column

how to set focus on edition column on click on add

   If GridView2.DataRowCount = 0 Then
            GridView2.FocusedColumn = GridView2.VisibleColumns(0)
            GridView2.SetFocusedValue(0)
            additem()
        End If

Jul 6, 2010

Filter ListBox using javascript

<head id="Head1" runat="server">
  <title>Demotitle>
head>
<script type="text/javascript" language="javascript">
  var myVals=new Array();
   function CacheValues()
   {
   var l =  document.getElementById('ListBox1');
 
   for (var i=0; i < l.options.length; i++)
    {
      myVals[i] = l.options[i].text;
    }
   }
 
  function SearchList()
  {
    var l document.getElementById('ListBox1');
    var tb = document.getElementById('TextBox1');
   
    l.options.length=0;
 
    if(tb.value == "")
    {
      for (var i=0; i < myVals.length; i++)
      {
        l.options[l.options.length] = new Option(myVals[i]);
      }
    }
    else{
 
      for (var i=0; i
      {
        if (myVals[i].toLowerCase().indexOf(tb.value.toLowerCase()) != -1)
        {
          l.options[l.options.length] = new Option(myVals[i]);
        }
        else
        {
          // do nothing
        }
      }
    }
  }
  function ClearSelection(lb)
  {
    lb.selectedIndex = -1;
  }
 
<body onload=CacheValues();>
  <form id="form1" runat="server">
  <input type="text" ID="TextBox1" onkeyup="return SearchList();"/><br />
  <select ID="ListBox1" Height="150px" Width="250px"  size="13" multiple="multiple">
  <option>Vincentoption>
  <option>Jenniferoption>
  <option>Shynneoption>
  <option>Christianoption>
  <option>Helenoption>
  <option>Vladioption>
  <option>Beeoption>
  <option>Jeromeoption>
  <option>Vinzoption>
  <option>Churchilloption>
  <option>Rodoption>
  <option>Markoption>
  select>
  form>
body>
html>
 

Jun 16, 2010

Update Panel With Dynamic Controls

I am dynamically adding DropDownLists to a table cell. When a DropDownList's selection is changed, I want to update a value ("Label1") on the screen. This value is contained within the Updatepanel ("UP1"). (The DropDownLists are created based on values from a database.) When I create each DropDownList, I also add it to the for the UpdatePanel. This allow the UpdatePanel to be redrawn when the values in the DropDownLists change.

In the example, when I change the selectedvalue in the DropDownList, the "Label1" value on the screen is correctly changed each time but only the 1st, 3rd, 5th, etc. change results in an AsyncPostback. The 2nd, 4th, 6th, etc. results in a full postback. It seems to me that on the 2nd, 4th, etc. occurrence, the UpdatePanel has somehow lost it's (during the last AsyncPostback). When a full postback occurs, everything is reset so that's why it works again the next time.

I know I need to re-add the dynamic trigger to the UpdatePanel, but I don't really know where I should add them.

Thanks for any help you might be able to provide.








Current Value:




Public currentValue As Integer = 0

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim tr As New TableRow
Dim tc As New TableCell
Dim DDL As New DropDownList
DDL.Items.Add(New ListItem("Item #1", 1))
DDL.Items.Add(New ListItem("Item #2", 2))
DDL.ID = "DDL"
DDL.AutoPostBack = True
AddHandler DDL.SelectedIndexChanged, AddressOf SelectionChanged
Dim asyncTrigger As New AsyncPostBackTrigger
asyncTrigger.ControlID = "DDL"
asyncTrigger.EventName = "SelectedIndexChanged"
UP1.Triggers.Add(asyncTrigger)
tc.Controls.Add(DDL)
tr.Cells.Add(tc)
Table1.Rows.Add(tr)
End Sub

Protected Sub SelectionChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim thisDDL As DropDownList = CType(sender, DropDownList)
If ViewState("CurrentValue") = "" Then
currentValue = 0
Else
currentValue = CInt(ViewState("CurrentValue"))
End If
currentValue += thisDDL.SelectedValue
ViewState("CurrentValue") = CStr(currentValue)
Label1.Text = CStr(currentValue)
End Sub

Programmatically adding triggers to an UpdatePanel - Microsoft AJAX Library and ASP.NET 2.0 AJAX Extensions

If you want to add a control to fire the UpdatePanel, you have to add the trigger. You add this through the ScriptManager control. The method is .RegisterAsyncPostBackControl(ControlName);

I put this call in the Page_PreInit() method.

Jun 8, 2010

Integrate Youtube in ASP.NET

    I will discuss how to integrate youtube video in asp.net. Youtube provides the API to access the its huge database of videos. It also provides search facility and customized player for integration.
       First thing you need is to get developer key for accessing youtube service. You can get it from here. Once you get the developer you can use the API URL to retrieve youtube videos. The URL is,
   1: http://www.youtube.com/api2_rest
Fig – (1) Youtube API URL
       There specific parameters that you need to pass in query string to get desire result from youtube. See the list below,
   1: Parameter    Description
   2: =============================================================================================
   3: method       youtube.videos.list_by_tag (only needed as an explicit parameter for REST calls)
   4: dev_id       Your developer ID .
   5: tag          Search keyword
   6: page         The "page number" of results you want to retrieve (e.g. 1, 2, 3)
   7: per_page     The number of results you want to retrieve per page (default 20, maximum 100)
Fig – (2) Parameters for youtube querystring
       So from fig – (1) and (2) if you need to search video for asp.net and you need 10 records per page and page should display 3rd page the the URL will be,
   1: http://www.youtube.com/api2_rest?method=youtube.videos.list_by_tag&dev_id=YOURDEVELOPERID&tag=asp.net&page=3&per_page=10
   2:  
Fig – (3) Querystring for youtube video
      Use page=-1 and per_page=-1 to display all the videos on same page without paging. You will get reply in XML format from this URL. You can retrieve that XML as XML document and use XQuery to to get the desire result. OR you can generate dataset from that XML using ReadXML method. I have used ReadXML method.
      This will create three tables (1) ut_response , (2) video_list and (3) video. in dataset. ut_response table contains the information whether the supplied DeveloperId is correct? If yes, the status field contains “ok”. video_list contains total number of videos returned. video table contains the information about the videos.
   1: private void GetYoutubeVedio()
   2: {      
   3:         
   4:         StringBuilder stbURL = new StringBuilder("http://www.youtube.com/api2_rest?");
   5:         stbURL.Append("method=youtube.videos.list_by_tag");
   6:         stbURL.Append("&dev_id=" + DEVELOPERKEY);
   7:         stbURL.Append("&tag=" + txtSearch.Text.Trim());
   8:         stbURL.Append("&page=-1&per_page=-1"); // you can add custom paging if desired
   9:         
  10:         DataSet ds = new DataSet();
  11:         ds.ReadXml(stbURL.ToString());
  12:  
  13:         dlYoutube.DataSource = ds.Tables[2];
  14:         dlYoutube.DataBind();
  15:         
  16:         
  17: }
Fig – (4)  Function to retrieve youtube video in ASP.NET
     You can retrieve youtube videos using above function in ASP.NET. Youtube also provides player integration details.
      Lets have a look at the code below. This code displays all youtube videos played in same asp.net page.
   1: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="GetYouTubeVedios.aspx.cs"
   2:     Inherits="Youtube_GetYouTubeVedios" %>
   3:  
   4: "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   5: "http://www.w3.org/1999/xhtml">
   6: "server">
   7:     Get Youtube Vedios
   8: 
   9: 
  10:     
  17: 
  18:     
"form1" runat="server">
  19:         
  20:             
  21:                 
  22:                     
  25:                 
  26:                 
  27:                     
  31:                 
  32:                 
  33:                     
  38:                 
  39:                 
  40:                     
  43:                 
  44:                 
  45:                     
 100:                 
 101:             
  23:                         Sample application to fetch vedios from Youtube. 
  24:                     
  28:                         First you need to create developer account in youtube to get developer key. You can get 
  29:                         "http://youtube.com/signup?next=/my_profile_dev" target="_blank">here.
  30:                     
  34:                         Enter Seach text :
  35:                         "txtSearch" runat="server" >
  36:                         "btnSearch" runat="server" Text="Search" OnClick="btnSearch_Click" />
  37:                     
  41:                         
  42:                     
"80%">
  46:                         "dlYoutube" runat="server" CellPadding="4" ForeColor="#333333" OnItemDataBound="dlYoutube_ItemDataBound">
  47:                             
  48:                                 
  49:                                     
  50:                                         
  53:                                     
  54:                                     
  55:                                         
  62:                                         
  90:                                     
  91:                                 
"2">
  51:                                             "lblTotle" Font-Bold="true" runat="server" Text='<%# Eval("title")%>'>
  52:                                         
"top">
  56:                                             <%--"aURL" style="text-decoration: none" runat="server" href='<%# Eval("url")%>'>
  57:                                                 "imgImage" runat="server" ImageUrl='<%# Eval("thumbnail_url")%>' />
  58:                                             --%>
  59:                                             
"server" id="player">
  60:                                             "ltrl" runat="server">
  61:                                         
"top">
  63:                                             
"100%"> 
  64:                                                 
  65:                                                     
  68:                                                     
  71:                                                 
  72:                                                 
  73:                                                     
  76:                                                     
  79:                                                 
  80:                                                 
  81:                                                     
  84:                                                     
  87:                                                 
  88:                                             
  66:                                                         "lblAuthor" runat="server" Text="Author : ">
  67:                                                     
  69:                                                         "lblAuthorName" runat="server" Text='<%# Eval("author")%>'>
  70:                                                     
"top">
  74:                                                         "Label1" runat="server" Text="Description : ">
  75:                                                     
  77:                                                         "Label2" runat="server" Text='<%# Eval("description")%>'>
  78:                                                     
  82:                                                         "Label3" runat="server" Text="Rating : ">
  83:                                                     
  85:                                                         "Label4" runat="server" Text='<%# Eval("rating_avg")%>'>
  86:                                                     
  89:                                         
  92:                             
  93:                             "#5D7B9D" Font-Bold="True" ForeColor="White" />
  94:                             "#E2DED6" Font-Bold="True" ForeColor="#333333" />
  95:                             "White" ForeColor="#284775" />
  96:                             "#F7F6F3" ForeColor="#333333" />
  97:                             "#5D7B9D" Font-Bold="True" ForeColor="White" />
  98:                         
  99:                     
 102:         
 103:     
 104: 
 105: 
Fig – (5) Youtube asp.net aspx page.
   1: using System;
   2: using System.Data;
   3: using System.Configuration;
   4: using System.Collections;
   5: using System.Web;
   6: using System.Web.Security;
   7: using System.Web.UI;
   8: using System.Web.UI.WebControls;
   9: using System.Web.UI.WebControls.WebParts;
  10: using System.Web.UI.HtmlControls;
  11: using System.Text;
  12:  
  13:  
  14: public partial class Youtube_GetYouTubeVedios : System.Web.UI.Page
  15: {
  16:     const string DEVELOPERKEY = "YOUR DEVELOPER KEY";
  17:  
  18:     protected void Page_Load(object sender, EventArgs e)
  19:     {
  20:         
  21:     }
  22:  
  23:     private void GetVedio()
  24:     {      
  25:         
  26:         StringBuilder stbURL = new StringBuilder("http://www.youtube.com/api2_rest?");
  27:         stbURL.Append("method=youtube.videos.list_by_tag");
  28:         stbURL.Append("&dev_id=" + DEVELOPERKEY);
  29:         stbURL.Append("&tag=" + txtSearch.Text.Trim());
  30:         stbURL.Append("&page=-1&per_page=-1"); // you can add custom paging if desired
  31:         
  32:         DataSet ds = new DataSet();
  33:         ds.ReadXml(stbURL.ToString());
  34:  
  35:         dlYoutube.DataSource = ds.Tables[2];
  36:         dlYoutube.DataBind();
  37:         
  38:         
  39:     }
  40:  
  41:     protected void btnSearch_Click(object sender, EventArgs e)
  42:     {
  43:         GetVedio();
  44:     }
  45:     protected void dlYoutube_ItemDataBound(object sender, DataListItemEventArgs e)
  46:     {
  47:         if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
  48:         {
  49:             HtmlControl div = (HtmlControl)e.Item.FindControl("player");
  50:             Literal objL = (Literal)e.Item.FindControl("ltrl");
  51:             objL.Text = "";
  52:         }
  53:     }
  54: }
Fig – (6) Youtube asp.net aspx.cs page.

Happy Programming !!!