Skip to content

Instantly share code, notes, and snippets.

@yevhen
Created October 3, 2017 16:48
Show Gist options
  • Save yevhen/2f53f923d30b2d5e1ed0acb13034475c to your computer and use it in GitHub Desktop.
Save yevhen/2f53f923d30b2d5e1ed0acb13034475c to your computer and use it in GitHub Desktop.
Code in question - Stack trace is lost
// https://stackoverflow.com/questions/46467275/weird-stack-trace-growth-with-async-await-and-taskcompletionsource
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using System.Threading.Tasks;
namespace BatchErrorWithTcs
{
class Program
{
static readonly List<TaskCompletionSource<bool>> buffer =
new List<TaskCompletionSource<bool>>();
static Timer timer;
public static void Main()
{
var outstanding = Enumerable.Range(1, 2)
.Select(Enqueue)
.ToList();
timer = new Timer(x => Flush(), null,
TimeSpan.FromSeconds(1),
TimeSpan.FromMilliseconds(-1));
outstanding.ForEach(WaitExecute);
Console.ReadKey();
}
static void WaitExecute(Task t)
{
try
{
t.GetAwaiter().GetResult();
}
catch (Exception e)
{
Console.WriteLine($"Stack Trace:\nLength:{e.StackTrace.Length}\n{e.StackTrace}\n");
}
}
static async Task Enqueue(int i)
{
var task = new TaskCompletionSource<bool>();
buffer.Add(task);
await task.Task;
}
static void Flush()
{
try
{
Some();
}
catch (Exception e)
{
foreach (var each in buffer)
each.TrySetException(DeepClone(e));
}
}
static void Some() => throw new Exception("test");
public static T DeepClone<T>(T obj)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (T)formatter.Deserialize(ms);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment