37 lines
1.3 KiB
C#
37 lines
1.3 KiB
C#
using System;
|
|
using System.Threading;
|
|
|
|
namespace Npgsql;
|
|
|
|
/// <summary>
|
|
/// This mechanism is used to temporarily set the current synchronization context to null while
|
|
/// executing Npgsql code, making all await continuations execute on the thread pool. This replaces
|
|
/// the need to place ConfigureAwait(false) everywhere, and should be used in all surface async methods,
|
|
/// without exception.
|
|
///
|
|
/// Warning: do not use this directly in async methods, use it in sync wrappers of async methods
|
|
/// (see https://github.com/npgsql/npgsql/issues/1593)
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// https://stackoverflow.com/a/28307965/640325
|
|
/// </remarks>
|
|
static class NoSynchronizationContextScope
|
|
{
|
|
internal static Disposable Enter() => new(SynchronizationContext.Current);
|
|
|
|
internal struct Disposable : IDisposable
|
|
{
|
|
readonly SynchronizationContext? _synchronizationContext;
|
|
|
|
internal Disposable(SynchronizationContext? synchronizationContext)
|
|
{
|
|
if (synchronizationContext != null)
|
|
SynchronizationContext.SetSynchronizationContext(null);
|
|
|
|
_synchronizationContext = synchronizationContext;
|
|
}
|
|
|
|
public void Dispose()
|
|
=> SynchronizationContext.SetSynchronizationContext(_synchronizationContext);
|
|
}
|
|
} |