Skip to content

Instantly share code, notes, and snippets.

@alextercete
Created September 22, 2014 12:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alextercete/1acbaf93605383fcea51 to your computer and use it in GitHub Desktop.
Save alextercete/1acbaf93605383fcea51 to your computer and use it in GitHub Desktop.
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncAndAwaitSecrets.Mistakes
{
public interface IDependency<T>
{
Task<object> BeforeAsync();
Task<T> AfterAsync(object result);
Task<T> SomethingAsync();
Task<T> SomethingAsync(CancellationToken token);
Task<T> SomethingAsync(Func<object, Task<T>> callback);
}
}
using System.Threading.Tasks;
namespace AsyncAndAwaitSecrets.Mistakes
{
public class TheAlmostAsync<T>
{
private readonly IDependency<T> _dependency;
public TheAlmostAsync(IDependency<T> dependency)
{
_dependency = dependency;
}
public T Something()
{
return SomethingAsync().Result;
}
public async Task<T> SomethingAsync()
{
var result = await _dependency.BeforeAsync();
return await _dependency.AfterAsync(result);
}
}
public class TheAlmostAsyncFixed<T>
{
private readonly IDependency<T> _dependency;
public TheAlmostAsyncFixed(IDependency<T> dependency)
{
_dependency = dependency;
}
public T Something()
{
return SomethingAsync().Result;
}
public async Task<T> SomethingAsync()
{
var result = await _dependency.BeforeAsync().ConfigureAwait(false);
return await _dependency.AfterAsync(result).ConfigureAwait(false);
}
}
}
using System.Threading.Tasks;
namespace AsyncAndAwaitSecrets.Mistakes
{
public class TheForgottenCall<T>
{
private readonly IDependency<T> _dependency;
public TheForgottenCall(IDependency<T> dependency)
{
_dependency = dependency;
}
public Task SomethingAsync()
{
SomethingNotAsync();
return CompletedTask;
}
private async void SomethingNotAsync()
{
await _dependency.BeforeAsync();
}
public Task AfterAsync(object result)
{
_dependency.AfterAsync(result);
return CompletedTask;
}
private static Task CompletedTask
{
get { return Task.FromResult(0); }
}
}
public class TheForgottenCallFixed<T>
{
private readonly IDependency<T> _dependency;
public TheForgottenCallFixed(IDependency<T> dependency)
{
_dependency = dependency;
}
public async Task SomethingAsync()
{
await SomethingNotAsync();
}
private async Task SomethingNotAsync()
{
await _dependency.BeforeAsync();
}
public Task AfterAsync(object result)
{
return _dependency.AfterAsync(result);
}
}
public class TheForgottenCallReallyFixed<T>
{
private readonly IDependency<T> _dependency;
public TheForgottenCallReallyFixed(IDependency<T> dependency)
{
_dependency = dependency;
}
public Task SomethingAsync()
{
return SomethingNotAsync();
}
private Task SomethingNotAsync()
{
return _dependency.BeforeAsync();
}
public Task AfterAsync(object result)
{
return _dependency.AfterAsync(result);
}
}
}
using System.Threading;
using System.Threading.Tasks;
namespace AsyncAndAwaitSecrets.Mistakes
{
public class TheIgnoredCancellation<T>
{
private readonly IDependency<T> _dependency;
public TheIgnoredCancellation(IDependency<T> dependency)
{
_dependency = dependency;
}
public Task<T> SomethingAsync(CancellationToken token)
{
return _dependency.SomethingAsync();
}
}
public class TheIgnoredCancellationFixed<T>
{
private readonly IDependency<T> _dependency;
public TheIgnoredCancellationFixed(IDependency<T> dependency)
{
_dependency = dependency;
}
public Task<T> SomethingAsync(CancellationToken token)
{
return _dependency.SomethingAsync(token);
}
}
}
using System.Threading.Tasks;
using System.Web;
namespace AsyncAndAwaitSecrets.Mistakes
{
public class TheMissingContext<T>
{
private readonly IDependency<T> _dependency;
public TheMissingContext(IDependency<T> dependency)
{
_dependency = dependency;
}
public async Task<T> SomethingAsync()
{
var result = await _dependency.BeforeAsync().ConfigureAwait(false);
// HttpContext.Current == null
return await _dependency.AfterAsync(result).ConfigureAwait(false);
}
}
public class TheMissingContextFixed<T>
{
private readonly IDependency<T> _dependency;
public TheMissingContextFixed(IDependency<T> dependency)
{
_dependency = dependency;
}
public async Task<T> SomethingAsync()
{
var context = HttpContext.Current;
var result = await _dependency.BeforeAsync().ConfigureAwait(false);
HttpContext.Current = context;
return await _dependency.AfterAsync(result).ConfigureAwait(false);
}
}
}
using System.Threading.Tasks;
namespace AsyncAndAwaitSecrets.Mistakes
{
public class TheNullReturn<T>
{
private readonly IDependency<T> _dependency;
public TheNullReturn(IDependency<T> dependency)
{
_dependency = dependency;
}
public Task<T> AfterAsync(object result)
{
if (result == null)
return null;
return _dependency.AfterAsync(result);
}
}
public class TheNullReturnFixed<T> where T : class
{
private readonly IDependency<T> _dependency;
public TheNullReturnFixed(IDependency<T> dependency)
{
_dependency = dependency;
}
public Task<T> AfterAsync(object result)
{
if (result == null)
return Task.FromResult<T>(null);
return _dependency.AfterAsync(result);
}
}
}
using System.Threading.Tasks;
namespace AsyncAndAwaitSecrets.Mistakes
{
public class ThePseudoAsync<T>
{
public async Task<T> SomethingAsync()
{
return default(T);
}
}
}
using System.Threading.Tasks;
namespace AsyncAndAwaitSecrets.Mistakes
{
public class TheSuperAsync<T>
{
private readonly IDependency<T> _dependency;
public TheSuperAsync(IDependency<T> dependency)
{
_dependency = dependency;
}
public async Task<T> SomethingAsync()
{
return await _dependency.SomethingAsync(async result => await _dependency.AfterAsync(result));
}
}
public class TheSuperAsyncFixed<T>
{
private readonly IDependency<T> _dependency;
public TheSuperAsyncFixed(IDependency<T> dependency)
{
_dependency = dependency;
}
public Task<T> SomethingAsync()
{
return _dependency.SomethingAsync(result => _dependency.AfterAsync(result));
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace AsyncAndAwaitSecrets.Mistakes
{
public class TheThreadsDispute<T>
{
private readonly IDependency<T> _dependency;
public TheThreadsDispute(IDependency<T> dependency)
{
_dependency = dependency;
}
public T Something()
{
return Task.Run(() => _dependency.SomethingAsync()).Result;
}
public IList<T> Somethings(int count)
{
var results = new List<T>(count);
Parallel.For(0, count, i => results[i] = _dependency.SomethingAsync().Result);
return results;
}
}
public class TheThreadsDisputeFixed<T>
{
private readonly IDependency<T> _dependency;
public TheThreadsDisputeFixed(IDependency<T> dependency)
{
_dependency = dependency;
}
public T Something()
{
return _dependency.SomethingAsync().Result;
}
public IList<T> Somethings(int count)
{
var tasks = Enumerable.Range(0, count).Select(i => _dependency.SomethingAsync());
return Task.WhenAll(tasks).Result;
}
}
public class TheThreadsDisputeReallyFixed<T>
{
private readonly IDependency<T> _dependency;
public TheThreadsDisputeReallyFixed(IDependency<T> dependency)
{
_dependency = dependency;
}
public Task<T> SomethingAsync()
{
return _dependency.SomethingAsync();
}
public async Task<IList<T>> SomethingsAsync(int count)
{
var tasks = Enumerable.Range(0, count).Select(i => _dependency.SomethingAsync());
return await Task.WhenAll(tasks);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment