• Stars
    star
    185
  • Rank 207,291 (Top 5 %)
  • Language
    C#
  • License
    MIT License
  • Created over 7 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An async/await-friendly lock for .NET, complete with asynchronous waits, safe reëntrance, and more.

AsyncLock: An async/await-friendly lock

NuGet

AsyncLock is an async/await-friendly lock implementation for .NET Standard, making writing code like the snippet below (mostly) possible:

lock (_lockObject)
{
    await DoSomething();
}

Unlike most other so-called "async locks" for C#, AsyncLock is actually designed to support the programming paradigm lock encourages, not just the technical elements. You can read more about the pitfalls with other so-called asynchronous locks and the difficulties of creating a reentrance-safe implementation here.

With AsyncLock, you don't have to worry about which thread is running what code in order to determine whether or not your locks will have any effect or if they'll be bypassed completely, you just write code the way you normally would and you'll find AsyncLock to correctly marshal access to protected code segments.

Using AsyncLock

There are only three functions to familiarize yourself with: the AsyncLock() constructor and the two locking variants Lock()/LockAsync() .

AsyncLock() creates a new asynchronous lock. A separate AsyncLock should be used for each "critical operation" you will be performing. (Or you can use a global lock just like some people still insist on using global mutexes and semaphores. We won't judge too harshly.)

Everywhere you would normally use lock (_lockObject) you will now use one of

  • using (_lock.Lock()) or
  • using (await _lock.LockAsync())

That's all there is to it!

Async-friendly locking by design

Much like theSemaphoreSlim class, AsyncLock offers two different "wait" options, a blocking Lock() call and the asynchronous LockAsync() call. The utmost scare should be taken to never call LockAsync() without an await before it, for obvious reasons.

Upon using LockAsync(), AsyncLock will attempt to obtain exclusive access to the lock. Should that not be possible in the current state, it will cede its execution slot and return to the caller, allowing the system to marshal resources efficiently as needed without blocking until the lock becomes available. Once the lock is available, the AsyncLock() call will resume, transferring execution to the protected section of the code.

AsyncLock usage example

private class AsyncLockTest
{
    var _lock = new AsyncLock();

    void Test()
    {
        // The code below will be run immediately (likely in a new thread)
        Task.Run(async () =>
             {
                 // A first call to LockAsync() will obtain the lock without blocking
                 using (await _lock.LockAsync())
                 {
                     // A second call to LockAsync() will be recognized as being
                     // reentrant and permitted to go through without blocking.
                     using (await _lock.LockAsync())
                     {
                         // We now exclusively hold the lock for 1 minute
                         await Task.Delay(TimeSpan.FromMinutes(1));
                     }
                 }
             }).Wait(TimeSpan.FromSeconds(30));

        // This call to obtain the lock is made synchronously from the main thread.
        // It will, however, block until the asynchronous code which obtained the lock
        // above finishes.
        using (_lock.Lock())
        {
            // Now we have obtained exclusive access.
            // <Safely perform non-thread-safe operation safely here>
        }
    }
}

More Repositories

1

pevents

Implementation of Win32 events for *nix platforms, built on top of pthreads.
C++
265
star
2

CppSQLite

A simple and easy-to-use cross-platform C++ wrapper for the SQLite API. Fork of the CppSQLite project, originally by Rob Groves, currently updated and maintained by NeoSmart Technologies.
C++
127
star
3

securestore-rs

A simple, encrypted, git-friendly, file-backed secrets manager for rust
Rust
126
star
4

tac

A high-performance, cross-platform file reverse utility
Rust
108
star
5

SecureStore

A .NET implementation of the cross-platform SecureStore (symmetrically-encrypted secrets) protocol
C#
93
star
6

RunInBash

Run Linux commands under WSL without leaving your PowerShell or CMD!
C++
92
star
7

unicode.net

A Unicode library for .NET, supporting UTF8, UTF16, and UTF32. With an extra helping of emoji for good measure 🔥🌶️😁
C#
87
star
8

msvcrt.lib

msvcrt.lib for linking against msvcrt.dll on all versions of Windows
C
82
star
9

SqliteCache

An ASP.NET Core IDistributedCache provider backed by SQLite
C#
80
star
10

prettysize-rs

Pretty-print file sizes and more
Rust
42
star
11

ln-win

JunctionPoint library and ln clone for Windows.
C++
33
star
12

udpproxy

Cross-platform UDP proxy
Rust
31
star
13

PrettySize.net

Format/print file sizes in a human-readable format.
C#
30
star
14

UrlBase64

A standards-compliant implementation of web/url-safe base64 encoding and decoding for .NET targets
C#
30
star
15

paste

A Windows utility that simply dumps the clipboard data to stdout
C++
26
star
16

rewrite

An in-place file rewrite utility, useful for redirecting output to same file as source.
Rust
26
star
17

betterpad

A better notepad. Still simple. Still fast.
C#
24
star
18

rsproxy

A simple, command-line TCP/UDP proxy server
Rust
23
star
19

cryptostream

Read and Write stream adapters for on-the-fly encryption and decryption for rust
Rust
21
star
20

rsevents

Auto- and manual-reset events for rust
Rust
19
star
21

uuidxx

Cross-platform C++ library for parsing and generating UUIDs or GUIDs. Windows, Mac, Linux, and BSD.
C++
19
star
22

LastPassTo1Password

A LastPass to 1Password converter.
C#
16
star
23

rsevents-extra

Extra event types built on top of rsevents
Rust
16
star
24

gmake-proxy

A BSD make (bmake) proxy that invokes GNU make (gmake) instead
Makefile
15
star
25

EasyBCD-Localization

EasyBCD localization files for NLT. Help us translate EasyBCD into your language, it's easy and rewarding!
Shell
14
star
26

StreamCompare

A .NET library and nuget package for stream comparison.
C#
12
star
27

UrlPreview

A .NET library for loading URL previews.
C#
11
star
28

collections

A collection of various data structures and containers for .NET Standard
C#
11
star
29

zipcat

Pipe contents of zip file to stdout, supporting multiple files.
Rust
11
star
30

open

Like macOS `open` but for Windows
C++
11
star
31

web

A collection of helpful classes and functions for writing ASP.NET projects, for both MVC and forms. Save time and effort with this small and highly-performant "framework."
C#
10
star
32

Localization

The NeoSmart Localization and Regionalization Toolkit (NLRT).
C#
9
star
33

TaskThreads

A Task-based System.Threading.Threads implementation for Universal Windows Platform applications.
C#
9
star
34

CargoMake

A Makefile for Cargo-based rust projects
Makefile
8
star
35

UtfRedirect

Helper application used to host a guest exe, transparently proxying bi-directional stdin and stdout traffic, forcing the console input and output codepages to UTF8/6501 in order to support internationalized stdin/stdout on Windows.
Rust
8
star
36

pkg-graph

A graphviz generator for pkg, the FreeBSD package manager
Rust
8
star
37

ExtensionMethods

A collection of helpful .NET extension methods for desktop and web development
C#
6
star
38

paypalnvp-dotnet

Minimal and lightweight PayPal NVP library for C# and .NET
C#
5
star
39

paypalnvp-php

Minimal and lightweight PayPal NVP Library for PHP.
PHP
4
star
40

run

A simple, invisible application launcher for Windows
C++
4
star
41

xf86-video-scfb

FreeBSD syscons framebuffer Xorg driver
Shell
4
star
42

nettest

Tiny and bare-bones command-line utility to test for the presence of an internet connection on Windows.
Rust
4
star
43

ignore-result

Adds `.ignore()` to rust `Result` types
Rust
4
star
44

RedisDictionary

A redis-backed persistent dictionary for C#, .NET, and .NET Core
C#
3
star
45

UwpTaskbarIcon

Taskbar icon library for Windows 10
C#
3
star
46

linqplus

Additional LINQ methods optimized for specific data structures, functional LINQ methods, and more.
C#
3
star
47

textlist

Generate properly formatted and grammatically correct text lists from arrays and IEnumerables.
C#
2
star
48

hashing.net

NeoSmart hashing library for .NET
C#
2
star
49

synchronization

A collection of async-friendly synchronization objects for .NET and .NET Core
C#
2
star
50

Stream.CopyTo

A Stream.CopyTo() implementation for .NET 2.0, 3.0, and 3.5
C#
2
star
51

bandit.net

A multi-armed bandit A/B testing library for .NET platforms
C#
2
star
52

nst-ses

Community fork of Amazon's AWS SES (Simple Email Service) Perl framework. Contains important compatibility and integration improvements.
Perl
2
star
53

ms-sys

C
2
star
54

nst-log

A basic and cross-platform logging library for C++ applications. Features an easy to use singleton class, a simple API, convience wrappers, and very little overhead. For those looking for a logging library that doesn't overwhelm.
C++
2
star
55

showkeys

Rust
1
star
56

wp-prism

A githubesque syntax highlighting and code fencing plugin for WordPress.
PHP
1
star
57

relaunch

A simple, cross-platform, zero-configuration process monitor/relauncher
Rust
1
star
58

hivexx

C++ wrapper around the excellent hivex library, focused on safety and speed.
C++
1
star
59

UwpCache

An object cache for UWP applications.
C#
1
star