// Load made a task private static Task <IAsyncLoaded> Load(this IAsyncLoaded loadable) { if (loadable.IsLoaded && loadable.IsReady) { return(Task.FromResult(loadable)); } else { TaskCompletionSource <IAsyncLoaded> tcs = new TaskCompletionSource <IAsyncLoaded>(); lock (waiting) { waiting.Add(new Tuple <IAsyncLoaded, TaskCompletionSource <IAsyncLoaded> >(loadable, tcs)); if (!_timer.Enabled) { _timer.Start(); } } return(tcs.Task); } }
public static Task <IAsyncLoaded> Load(this IAsyncLoaded loadable) { Action start = () => { running = true; ThreadPool.QueueUserWorkItem(delegate { while (true) { Tuple <IAsyncLoaded, TaskCompletionSource <IAsyncLoaded> >[] l; Thread.Sleep(100); lock (waiting) l = waiting.ToArray(); HashSet <Tuple <IAsyncLoaded, TaskCompletionSource <IAsyncLoaded> > > r = new HashSet <Tuple <IAsyncLoaded, TaskCompletionSource <IAsyncLoaded> > >(); foreach (var i in l) { if (i.Item1.IsLoaded) { i.Item2.SetResult(i.Item1); r.Add(i); } } lock (waiting) { waiting.RemoveAll(e => r.Contains(e)); if (waiting.Count == 0) { running = false; break; } } } }); }; TaskCompletionSource <IAsyncLoaded> tcs = new TaskCompletionSource <IAsyncLoaded>(); if (loadable.IsLoaded) { tcs.SetResult(loadable); } else if (running) { lock (waiting) if (running) { waiting.Add(new Tuple <IAsyncLoaded, TaskCompletionSource <IAsyncLoaded> >(loadable, tcs)); } else { waiting.Add(new Tuple <IAsyncLoaded, TaskCompletionSource <IAsyncLoaded> >(loadable, tcs)); start(); } } else { lock (waiting) { waiting.Add(new Tuple <IAsyncLoaded, TaskCompletionSource <IAsyncLoaded> >(loadable, tcs)); start(); } } return(tcs.Task); }