Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
namespace WebApplication1
{
public class Run : HttpTaskAsyncHandler
{
static Dictionary<string, Tuple<DateTime, TaskCompletionSource<object>>> list = new Dictionary<string, Tuple<DateTime, TaskCompletionSource<object>>>();
public static Tuple<string, DateTime>[] List
{
get {
lock (list) {
return list.Select(x => Tuple.Create(x.Key, x.Value.Item1)).ToArray();
}
}
}
public static void SetResult(string key)
{
if (!ValidateKey(key)) {
return;
}
Tuple<DateTime, TaskCompletionSource<object>> t;
lock (list) {
if (!list.TryGetValue(key, out t)) {
return;
}
list.Remove(key);
}
t.Item2.SetResult(null);
}
static Timer timer = new Timer((_) => {
var now = DateTime.Now;
TaskCompletionSource<object>[] tcs;
lock (list) {
var expired = list.Where(x => now.Subtract(x.Value.Item1).TotalSeconds >= 5).ToArray();
tcs = expired.Select(x => x.Value.Item2).ToArray();
foreach (var x in expired) {
list.Remove(x.Key);
}
}
foreach (var x in tcs) {
x.SetResult(null);
}
}, null, 3000, 3000);
static Task Listen(string key)
{
var tcs = new TaskCompletionSource<object>();
lock (list) {
list.Add(key, Tuple.Create(DateTime.Now, tcs));
}
return tcs.Task;
}
static string CreateKey()
{
return Guid.NewGuid().ToString("N");
}
static bool ValidateKey(string s)
{
Guid _;
return Guid.TryParseExact(s, "N", out _);
}
public override async Task ProcessRequestAsync(HttpContext context)
{
var key = CreateKey();
await Listen(key);
if (!context.Response.IsClientConnected) {
return;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment