Here's some code that will do the work, using Linq. I don't know if it's in the form you were looking for, but the logic works with the data you gave us. You ought to be able to rearrange it into the proper shape for your app.
MODIFIED
var rows = new[] {
new { Id = 1, Name="Mike", TaskName="task1", StartTime=DateTime.Parse("2009-07-28 09:00:00"), EndTime=DateTime.Parse("2009-07-28 09:45:00") },
new { Id = 2, Name="Mike", TaskName="task2", StartTime=DateTime.Parse("2009-07-28 09:30:00"), EndTime=DateTime.Parse("2009-07-28 09:40:00") },
new { Id = 3, Name="Mike", TaskName="task3", StartTime=DateTime.Parse("2009-07-28 09:50:00"), EndTime=DateTime.Parse("2009-07-28 10:30:00") },
new { Id = 4, Name="Mike", TaskName="task4", StartTime=DateTime.Parse("2009-07-28 10:20:00"), EndTime=DateTime.Parse("2009-07-28 10:30:00") },
new { Id = 5, Name="Mike", TaskName="task5", StartTime=DateTime.Parse("2009-07-28 10:40:00"), EndTime=DateTime.Parse("2009-07-28 11:50:00") },
};
var ranges = rows.Select(x => new { StartTime = x.StartTime, EndTime = x.EndTime });
int rangeCount = 0;
while (ranges.Count() != rangeCount)
{
rangeCount = ranges.Count();
ranges = ranges.Select(x => new {
StartTime = ranges.Where(y => (y.StartTime <= x.StartTime && y.EndTime >= x.StartTime) || (y.StartTime <= x.EndTime && y.EndTime >= x.EndTime)).Min(y => y.StartTime),
EndTime = ranges.Where(y => (y.StartTime <= x.StartTime && y.EndTime >= x.StartTime) || (y.StartTime <= x.EndTime && y.EndTime >= x.EndTime)).Max(y => y.EndTime),
}).Distinct().ToList(); // ToList required to avoid recursion issues
}
TimeSpan gapTime = ranges.Max(x => x.EndTime) - ranges.Min(x => x.StartTime) - new TimeSpan(ranges.Sum(x => (x.EndTime - x.StartTime).Ticks));
System.Diagnostics.Trace.WriteLine(gapTime);