public static async Task <string> DoAsyncOperation(this SyncOverAsync runnable) { Console.WriteLine($"Entering DoAsyncOperation {Thread.CurrentThread.ManagedThreadId}"); await Task.Delay(2); Console.WriteLine($"Finishing DoAsyncOperation {Thread.CurrentThread.ManagedThreadId}"); return("Hello"); }
public static Task WrapInContext(this SyncOverAsync runnable, Action action) { return(Task.Factory.StartNew(() => { Console.WriteLine($"Entering SyncContext {Thread.CurrentThread.ManagedThreadId}"); action(); Console.WriteLine($"Exiting SyncContext {Thread.CurrentThread.ManagedThreadId}"); }, CancellationToken.None, TaskCreationOptions.None, scheduler)); }
public static void Explain(this SyncOverAsync runnable, TextWriter writer) { writer.WriteLine(@" - `Task.Result` or `Task.Wait` on asynchronous operations is much worse than calling truly synchronous APIs. Here is what happens - An asynchronous operation is kicked off. - The calling thread is blocked waiting for that operation to complete. When the asynchronous operation completes, it unblocks the code waiting on that operation. This takes place on another thread. - This leads to thread-pool starvation and service outages due to 2 threads being used instead of 1 to complete synchronous operations. - If a synchronization context is available it can even lead to deadlocks "); }
public void Remove(string key) => SyncOverAsync.Run(() => RemoveAsync(key));
public void Refresh(string key) => SyncOverAsync.Run(() => RefreshAsync(key));
public byte[] Get(string key) => SyncOverAsync.Run(() => GetAsync(key));
public void Set(string key, byte[] value, DistributedCacheEntryOptions options) => SyncOverAsync.Run(() => SetAsync(key, value, options));