Q:

Understanding Lambda expressions and delegates

I have been trying to figure this out for quite sometime (reading online blogs and articlaes), but so far unsuccessful.  
What are delegates? What are Lambda Expressions? Advantages and disadvantages of both? Possible best practice of when to use one or the other?
Thanks in advance.

A:

Delegates are methods that you can use as variables, like strings etc. For example you can declare a delegate method with one argument:
delegate void OneArgumentDelegate(string argument);
It doesn't do anything, much like an interface. If you have a method in any class with one argument like this:
void SomeMethod(string someArgument) {}
It matches the signature of the delegate, and thus can be assigned to a variable of its type:
OneArgumentDelegate ThisIsAVariable = new OneArgumentDelegate(SomeMethod);
OneArgumentDelegate ThisIsAlsoAVariable = SomeMethod; // Shorthand works too
These can then be passed as arguments to methods and invoked, like so:
void Main()
{
  DoStuff(PrintString);
}

void PrintString(string text)
{
  Console.WriteLine(text);
}

void DoStuff(OneArgumentDelegate action) 
{
  action("Hello!");
}
This will output Hello!.
Lambda expressions are a shorthand for the DoStuff(PrintString) so you don't have to create a method for every delegate variable you're going to use. You 'create' a temporary method that's passed on to the method. It works like this:
DoStuff(string text => Console.WriteLine(text)); // single line
DoStuff(string text => // multi line
{
  Console.WriteLine(text);
  Console.WriteLine(text);
});
Lambda expressions are just a shorthand, you might as well create a seperate method and pass it on. I hope you understand it better now ;-)

A:

Delegate is an object that hold a reference to a function. Several different delegates may point to the same function. A delegate's type defines the footprint of a function it may point to.
Lambda expression is a function that doesn't have name. The only way to execute this function is to have a delegate pointing to the function. Lambda expressions are usually defined in place where you need a delegate to a function with a given footprint. This is useful to make code less verbose and at the same time more descriptive and flexible
I would suggest that you use a named function and a delegate to it whenever you have some code that is going to be called from different places. A common example is an event listener that you want to attach to several event producers. 
Another point to consider writing a separate function is the complexity of the code. It isn't going to help anyone if you write a whole program inside a lambda expression.
On the other hand, you often need some trivial processing that you want to be executed in a callback manner. This is the point where you might love the lambda expressions. 
What is very nice about lambda expressions that they inherit the scope they were defined in, so that you can easily your variables inside the lambda expression, and thus pass a lot of info inside. You should be careful though, see the Remarks section of 
this article.
Labdas are brilliant in conjunction with LINQ.
To conclude, I have to quote yet another must-read msdn section:

When you use method-based syntax to call the Where  method in the Enumerable  class (as you do in LINQ to Objects and LINQ to XML) the parameter is a delegate type System.Func. A lambda expression is the most convenient way to create that delegate. When you call the same method in, for example, the System.Linq.Queryable class (as you do in LINQ to SQL) then the parameter type is an System.Linq.Expressions.Expression where Func is any Func delegates with up to sixteen input parameters. Again, a lambda expression is just a very concise way to construct that expression tree. The lambdas allow the Where calls to look similar although in fact the type of object created from the lambda is different.

A:

No one has mentioned anonymous delegates. You can create delegates on the fly, without declaring them:
public void Action(Func<int, int> func);
...
Action(delegate(int x) { return x*x; });

Which is just a more verbose version of the lambda syntax:
Action(x => x*x);

Also note that the lambda syntax has more aggressive type inference. Another difference is that the lambda notation can be used to declare expression trees:
public void Action(Expression<Func<int, int>>);
Action(x => x*x);

In which case what you get is not a function but a parse tree that you can examine at runtime. This is how linq queries build their sql, for example.
edit
To more directly answer the question of when to use one or the other:
You rarely need to declare a new delegate type yourself, although it is occasionally helpful. The framework provides several Func<> types, along with Action<T> and Predicate<T> which are usually all that you need.
When creating a function 'on the fly', there is no advantage to using the anonymous delegate syntax instead of the lambda syntax. Since the lambda syntax is more concise and type-inferred, prefer it.

