Files
ArchiSteamFarm/packages/Microsoft.Bcl.1.1.10/lib/net40/System.Runtime.xml
JustArchi a8045ac50b Fix async/await with ConcurrentHashSet
Now this is a nice bug that was found accidentally by ArchiBoT...
ReaderWriterLockSlim() is very decent solution, but it's thread-based, and we're using our ConcurrentHashSet in mixed async/sync context. This means that if we use something like:
foreach (var item in concHashSet) {
    await AnythingAsync().ConfigureAwait(false);
}
It's totally possible that we'll request read lock as thread 1, and release the read lock as thread 2, which will lead to RWLock exception => System.Threading.SynchronizationLockException: The read lock is being released without being held.
Fortunately it looks like we didn't have any scenario like this in ASF, as this was possible only when we async/await while enumerating over ConcurrentHashSet, so that specific bug didn't affect ASF codebase (yet). Still, I must fix this as current implementation is not thread-safe, so our HashSet is in fact not concurrent in the first place.
I analyzed possible solutions and there are basically 3: either using ConcurrentDictionary and wrapping around it, replacing lock with SemaphoreSlim, or using third-party AsyncReaderWriterLock from StephenCleary. SemaphoreSlim entirely kills the concept of multiple readers one writer, and could affect performance negatively, moreover - it doesn't support upgreadable lock scenario we have with ReplaceIfNeededWith(). Concurrent dictionary would be nice if I didn't have that awful memory hit from storing mandatory pointless value, plus I don't really like concept of wrapping around conc dictionary if I can simply use it right away and drop my conc hashset entirely. AsyncReaderWriterLock seem to be really well written, and works on Mono + should be compatible with .NET core in the future, so we should go for it as it's the best bet both performance-wise and memory-wise.
This brings another package dependency and changes a bit backend of ConcurrentHashSet
2017-02-07 20:14:51 +01:00

57 lines
2.8 KiB
XML

<?xml version="1.0"?>
<doc>
<assembly>
<name>System.Runtime</name>
</assembly>
<members>
<member name="T:System.IProgress`1">
<summary>Defines a provider for progress updates.</summary>
<typeparam name="T">The type of progress update value.</typeparam>
</member>
<member name="M:System.IProgress`1.Report(`0)">
<summary>Reports a progress update.</summary>
<param name="value">The value of the updated progress.</param>
</member>
<member name="T:System.Runtime.CompilerServices.AsyncStateMachineAttribute">
<summary>Identities the async state machine type for this method.</summary>
</member>
<member name="T:System.Runtime.CompilerServices.StateMachineAttribute">
<summary>Identities the state machine type for this method.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.StateMachineAttribute.#ctor(System.Type)">
<summary>Initializes the attribute.</summary>
<param name="stateMachineType">The type that implements the state machine.</param>
</member>
<member name="P:System.Runtime.CompilerServices.StateMachineAttribute.StateMachineType">
<summary>Gets the type that implements the state machine.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncStateMachineAttribute.#ctor(System.Type)">
<summary>Initializes the attribute.</summary>
<param name="stateMachineType">The type that implements the state machine.</param>
</member>
<member name="T:System.Runtime.CompilerServices.CallerMemberNameAttribute">
<summary>
Allows you to obtain the method or property name of the caller to the method.
</summary>
</member>
<member name="T:System.Runtime.CompilerServices.CallerLineNumberAttribute">
<summary>
Allows you to obtain the line number in the source file at which the method is called.
</summary>
</member>
<member name="T:System.Runtime.CompilerServices.CallerFilePathAttribute">
<summary>
Allows you to obtain the full path of the source file that contains the caller.
This is the file path at the time of compile.
</summary>
</member>
<member name="T:System.Runtime.CompilerServices.IteratorStateMachineAttribute">
<summary>Identities the iterator state machine type for this method.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.IteratorStateMachineAttribute.#ctor(System.Type)">
<summary>Initializes the attribute.</summary>
<param name="stateMachineType">The type that implements the state machine.</param>
</member>
</members>
</doc>