Recently I switched from HashSet to a collection someone else posted called 'ConcurrentHashSet', I decided to opt out of locking my own HashSet as I was using it a lot and just seemed a safer bet to use a pre-made thread-safe class, but I've hit an issue.
When I used HashSet (the default HashSet class) I was getting my HashSet values using the First and FirstOrDefault methods, the issue is I can no longer use these methods and I'm not sure why or how to re-implement them, is it even possible? It may be really simple, I'm unsure.
I was hoping someone would know and could point me in the right direction. Heres the class that I picked up off another stack overflow answer, although I'm not sure if this is the original.
public class ConcurrentHashSet<T> : IDisposable
{
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
private readonly HashSet<T> _hashSet = new HashSet<T>();
public bool TryAdd(T item)
{
_lock.EnterWriteLock();
try
{
return _hashSet.Add(item);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
}
public void Clear()
{
_lock.EnterWriteLock();
try
{
_hashSet.Clear();
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
}
public bool Contains(T item)
{
_lock.EnterReadLock();
try
{
return _hashSet.Contains(item);
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
public bool TryRemove(T item)
{
_lock.EnterWriteLock();
try
{
return _hashSet.Remove(item);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
}
public int Count
{
get
{
_lock.EnterReadLock();
try
{
return _hashSet.Count;
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_lock?.Dispose();
}
}
~ConcurrentHashSet()
{
Dispose(false);
}
}
Internally the custom class you have posted uses a HashSet<T> to store the data. So you can still make use of the methods you mentioned, First and FirstOrDefault, provided that you would do it in a thread safe way. For instance the implementation of FirstOrDefault would have been something like this:
public T TryGetFirstOrDefault()
{
_lock.EnterReadLock();
try
{
return _hashSet.FirstOrDefault();
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
Update
You could generalize the above by passing a predicate:
public T TryGetFirstOrDefault(Func<T, bool> predicate)
{
_lock.EnterReadLock();
try
{
return _hashSet.FirstOrDefault(x=>predicate(x));
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
So in case you have a ConcurrentHashSet<Player>, you could use it for instance as:
var player = concurrentHashSetOfPlayers.TryGetFirstOrDefault(x=>x.Id == playerId);
Related
I have a Subject where I subscribe methods that should be called when a determined event in a game happens.
public Subject<SomeEvent> TestSubject = new Subject<SomeEvent>();
Some instances subscribe to that Subject.
TestSubject.Subscribe(MyMethod);
My objective is to count how many methods have been subscribed to that Subject. I've seen some examples using Count() extension but I need an int as a return value so then I can use it somewhere else, and Count() returns an IObservable.
if (subjectCount > 0)
{
DoSomething();
}
Is there any way to get the number of subscriptions on a subject or do I need to keep track of them manually (having a public int SubjectSubcriptions and adding 1 everytime I subscribe a method) ?
Easiest way would be to create your own implementation of ISubject with a wrapper around a subject.
public class CountSubject<T> : ISubject<T>, IDisposable
{
private readonly ISubject<T> _baseSubject;
private int _counter;
private IDisposable _disposer = Disposable.Empty;
private bool _disposed;
public int Count
{
get { return _counter; }
}
public CountSubject()
: this(new Subject<T>())
{
// Need to clear up Subject we created
_disposer = (IDisposable) _baseSubject;
}
public CountSubject(ISubject<T> baseSubject)
{
_baseSubject = baseSubject;
}
public void OnCompleted()
{
_baseSubject.OnCompleted();
}
public void OnError(Exception error)
{
_baseSubject.OnError(error);
}
public void OnNext(T value)
{
_baseSubject.OnNext(value);
}
public IDisposable Subscribe(IObserver<T> observer)
{
Interlocked.Increment(ref _counter);
return new CompositeDisposable(Disposable.Create(() => Interlocked.Decrement(ref _counter)),
_baseSubject.Subscribe(observer));
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_disposer.Dispose();
}
_disposed = true;
}
}
}
I am curious if this is only for testing purposes or not. If so, then the Rx-Testing nuget package has the tools to give you this information.
e.g. you can validate the number of subscription in a unit test like this
TestScheduler scheduler = new TestScheduler();
var obs = scheduler.CreateColdObservable(
ReactiveTest.OnNext(1, "foo"),
ReactiveTest.OnNext(1000, "bar"),
);
//Do some work that should add subscriptions.
Assert.AreEqual(expectedSubriptionCount, obs.Subscriptions);
I application that uses a a Interop Com Object. Therefore I had written a wrapper class, to do the freeing in the dispose or if this is not done in the finalizer. So I can use the using keyword, to ensure a freeing is done.
Is using this pattern a good way? Or is there even a class in the Framework that is doing this for me?
class ComWrapper<T> : IDisposable
{
private readonly T comObject;
private bool disposed = false;
public ComWrapper(T comObject)
{
this.comObject = comObject;
}
~ComWrapper()
{
this.Dispose(false);
}
public T ComObject
{
get
{
return this.comObject;
}
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
if (this.disposed)
{
return;
}
Marshal.FinalReleaseComObject(this.comObject);
}
}
I personally wouldn't recommend this because it seems somewhat pointless. But, I would recommend having a static class called Utility, with this method:
public static void disposeComObject<T>(ref T comObject)
{
if(Marshal.IsComObject(comObject) && comObject != null)
{
//You need to save the object
if(typeof(T) == typeof(Microsoft.Office.Interop.Excel.Workbook))
{
((Microsoft.Office.Interop.Excel.Workbook))comObject.Save();
((Microsoft.Office.Interop.Excel.Workbook))comObject.Close();
}
//You need to save the object
if(typeof(T) == typeof(Microsoft.Office.Interop.Excel.Application))
{
((Microsoft.Office.Interop.Excel.Application))comObject.Quit();
}
Marshal.ReleaseComObject(comObject);
comObject = null;
}
}
Now From Code, you can call this like so
...
Microsoft.Office.Interop.Excel comObject = null;
try{
//Open comObject
//Here I would call some functions, and have nested exceptions
}
catch(nestedException err)
{
//Handle at your discretion
}
finally{
Utility.disposeComObject(ref comObject);
}
This is specific to the Excel Namespace, but adjusting it should be easy enough.
I want to create a class that can be used to represent a dynamically computed value, and another class that represents a value can be the source (subject) for these dynamically computed values. The goal is that when the subject changes, the computed value is updated automatically.
It seems to me that using IObservable/IObserver is the way to go. Unfortunately I can't use the Reactive Extensions library, so I am forced to implement the subject/observer pattern from scratch.
Enough blabla, here are my classes:
public class Notifier<T> : IObservable<T>
{
public Notifier();
public IDisposable Subscribe(IObserver<T> observer);
public void Subscribe(Action<T> action);
public void Notify(T subject);
public void EndTransmission();
}
public class Observer<T> : IObserver<T>, IDisposable
{
public Observer(Action<T> action);
public void Subscribe(Notifier<T> tracker);
public void Unsubscribe();
public void OnCompleted();
public void OnError(Exception error);
public void OnNext(T value);
public void Dispose();
}
public class ObservableValue<T> : Notifier<T>
{
public T Get();
public void Set(T x);
}
public class ComputedValue<T>
{
public T Get();
public void Set(T x);
}
My implementation is lifted mostly from: http://msdn.microsoft.com/en-us/library/dd990377.aspx.
So what would the "right" way to do this be? Note: I don't care about LINQ or multi-threading or even performance. I just want it to be simple and easy to understand.
If I were you I would try to implement your classes as closely as possible to the way Rx has been implemented.
One of the key underlying principles is the use of relatively few concrete classes that are combined using a large number of operations. So you should create a few basic building blocks and use composition to bring them all together.
There are two classes I would take an initial look at under Reflector.NET: AnonymousObservable<T> & AnonymousObserver<T>. In particular AnonymousObservable<T> is used through-out Rx as the basis for instantiating observables. In fact, if you look at the objects that derive from IObservable<T> there are a few specialized implementations, but only AnonymousObservable<T> is for general purpose use.
The static method Observable.Create<T>() is essentially a wrapper to AnonymousObservable<T>.
The other Rx class that is clearly a fit for your requirements is BehaviorSubject<T>. Subjects are both observables and observers and BehaviorSubject fits your situation because it remembers the last value that is received.
Given these basic classes then you almost have all of the bits you need to create your specific objects. Your objects shouldn't inherit from the above code, but instead use composition to bring together the behaviour that you need.
Now, I would suggest some changes to your class designs to make them more compatible with Rx and thus more composible and robust.
I would drop your Notifier<T> class in favour of using BehaviourSubject<T>.
I would drop your Observer<T> class in favour of using AnonymousObserver<T>.
Then I would modify ObservableValue<T> to look like this:
public class ObservableValue<T> : IObservable<T>, IDisposable
{
public ObservableValue(T initial) { ... }
public T Value { get; set; }
public IDisposable Subscribe(IObserver<T> observer);
public void Dispose();
}
The implementation of ObservableValue<T> would wrap BehaviourSubject<T> rather than inherit from it as exposing the IObserver<T> members would allow access to OnCompleted & OnError which wouldn't make too much sense since this class represents a value and not a computation. Subscriptions would use AnonymousObservable<T> and Dispose would clean up the wrapped BehaviourSubject<T>.
Then I would modify ComputedValue<T> to look like this:
public class ComputedValue<T> : IObservable<T>, IDisposable
{
public ComputedValue(IObservable<T> source) { ... }
public T Value { get; }
public IDisposable Subscribe(IObserver<T> observer);
public void Dispose();
}
The ComputedValue<T> class would wrap AnonymousObservable<T> for all subscribers and and use source to grab a local copy of the values for the Value property. The Dispose method would be used to unsubscribe from the source observable.
These last two classes are the only real specific implementation your design appears to need - and that's only because of the Value property.
Next you need a static ObservableValues class for your extension methods:
public static class ObservableValues
{
public static ObservableValue<T> Create<T>(T initial)
{ ... }
public static ComputedValue<V> Compute<T, U, V>(
this IObservable<T> left,
IObservable<U> right,
Func<T, U, V> computation)
{ ... }
}
The Compute method would use an AnonymousObservable<V> to perform the computation and produce an IObservable<V> to pass to the constructor of ComputedValue<V> that is returned by the method.
With all this in place you can now write this code:
var ov1 = ObservableValues.Create(1);
var ov2 = ObservableValues.Create(2);
var ov3 = ObservableValues.Create(3);
var cv1 = ov1.Compute(ov2, (x, y) => x + y);
var cv2 = ov3.Compute(cv1, (x, y) => x * y);
//cv2.Value == 9
ov1.Value = 2;
ov2.Value = 3;
ov3.Value = 4;
//cv2.Value == 20
Please let me know if this is helpful and/or if there is anything that I can elaborate on.
EDIT: Also need some disposables.
You'll also need to implement AnonymousDisposable & CompositeDisposable to manage your subscriptions particularly in the Compute extension method. Take a look at the Rx implementations using Reflector.NET or use my versions below.
public sealed class AnonymousDisposable : IDisposable
{
private readonly Action _action;
private int _disposed;
public AnonymousDisposable(Action action)
{
_action = action;
}
public void Dispose()
{
if (Interlocked.Exchange(ref _disposed, 1) == 0)
{
_action();
}
}
}
public sealed class CompositeDisposable : IEnumerable<IDisposable>, IDisposable
{
private readonly List<IDisposable> _disposables;
private bool _disposed;
public CompositeDisposable()
: this(new IDisposable[] { })
{ }
public CompositeDisposable(IEnumerable<IDisposable> disposables)
{
if (disposables == null) { throw new ArgumentNullException("disposables"); }
this._disposables = new List<IDisposable>(disposables);
}
public CompositeDisposable(params IDisposable[] disposables)
{
if (disposables == null) { throw new ArgumentNullException("disposables"); }
this._disposables = new List<IDisposable>(disposables);
}
public void Add(IDisposable disposable)
{
if (disposable == null) { throw new ArgumentNullException("disposable"); }
lock (_disposables)
{
if (_disposed)
{
disposable.Dispose();
}
else
{
_disposables.Add(disposable);
}
}
}
public IDisposable Add(Action action)
{
if (action == null) { throw new ArgumentNullException("action"); }
var disposable = new AnonymousDisposable(action);
this.Add(disposable);
return disposable;
}
public IDisposable Add<TDelegate>(Action<TDelegate> add, Action<TDelegate> remove, TDelegate handler)
{
if (add == null) { throw new ArgumentNullException("add"); }
if (remove == null) { throw new ArgumentNullException("remove"); }
if (handler == null) { throw new ArgumentNullException("handler"); }
add(handler);
return this.Add(() => remove(handler));
}
public void Clear()
{
lock (_disposables)
{
var disposables = _disposables.ToArray();
_disposables.Clear();
Array.ForEach(disposables, d => d.Dispose());
}
}
public void Dispose()
{
lock (_disposables)
{
if (!_disposed)
{
this.Clear();
}
_disposed = true;
}
}
public IEnumerator<IDisposable> GetEnumerator()
{
lock (_disposables)
{
return _disposables.ToArray().AsEnumerable().GetEnumerator();
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public bool IsDisposed
{
get
{
return _disposed;
}
}
}
I have a list where it is entries can be updated, new data inserted or removed from 2 different threads.
Is it ok to use a public readonly object to lock when it is being used to interact to the other thread as to when it is locked or not or what would be the correct way to use this list across the 2 threads ?
You should always use a lock when accessing the list on different threads.
public class Sample
{
object synch = new object();
List<Something> list = new List<Something>();
void Add(Something something)
{
lock (synch) { list.Add(something); }
}
// Add the methods for update and delete.
}
You should wrap this in a class that handles the locking for you, or use a thread-safe collection, such as ConcurrentQueue<T> or one of the other collections in System.Collections.Concurrent.
Exposing the synchronization object to a public API is dangerous, and not a good practice.
First, read this article to understand why it's bad: http://blogs.msdn.com/b/jaredpar/archive/2009/02/11/why-are-thread-safe-collections-so-hard.aspx
Then, do it anyway like I did:
public abstract class ConcurrentCollection<T> : ICollection<T>
{
private List<T> List { get; set; }
public ConcurrentCollection()
{
this.List = new List<T>();
}
public T this[int index]
{
get
{
return this.List[index];
}
}
protected virtual void AddUnsafe(T item)
{
this.List.Add(item);
}
protected virtual void RemoveUnsafe(T item)
{
this.List.Remove(item);
}
protected virtual void ClearUnsafe()
{
this.List.Clear();
}
public void Add(T item)
{
lock (this.List)
{
this.AddUnsafe(item);
}
}
public bool Remove(T item)
{
lock (this.List)
{
this.RemoveUnsafe(item);
return true;
}
}
public void Clear()
{
lock (this.List)
{
this.ClearUnsafe();
}
}
public int Count
{
get
{
lock (this.List)
{
return this.List.Count;
}
}
}
public bool IsReadOnly
{
get
{
return false;
}
}
public bool Contains(T item)
{
lock (this.List)
{
return this.List.Contains(item);
}
}
public void CopyTo(T[] array, int arrayIndex)
{
lock (this.List)
{
this.List.CopyTo(array, arrayIndex);
}
}
public IEnumerator<T> GetEnumerator()
{
return new ConcurrentEnumerator<T>(this.List, this.List);
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException("Abstract concurrent enumerators not implemented.");
}
}
public class ConcurrentEnumerator<T> : IEnumerator<T>
{
private int Position = -1;
private List<T> Duplicate;
private object Mutex;
private ICollection<T> NonConcurrentCollection;
internal ConcurrentEnumerator(ICollection<T> nonConcurrentCollection, object mutex)
{
this.NonConcurrentCollection = nonConcurrentCollection;
this.Mutex = mutex;
lock (this.Mutex)
{
this.Duplicate = new List<T>(this.NonConcurrentCollection);
}
}
public T Current
{
get
{
return this.Duplicate[this.Position];
}
}
object IEnumerator.Current
{
get
{
return this.Current;
}
}
public bool MoveNext()
{
this.Position++;
lock (this.Mutex)
{
while (this.Position < this.Duplicate.Count && !this.NonConcurrentCollection.Contains(this.Current))
{
this.Position++;
}
}
return this.Position < this.Duplicate.Count;
}
public void Reset()
{
this.Position = -1;
}
public void Dispose() { }
}
// Standards have List as derived Collection...
public class ConcurrentList<T> : ConcurrentCollection<T> { }
This code is still not fully safe, for instance the Count example may still crash, but it allows for iteration, adding and removing across threads. If you want to expose the mutex, do so, then lock around it for your other code constructs like count and contains.
But it's still a bad idea.
Edit: Example usage.
ConcurrentList<string> list = new ConcurrentList<string>();
list.Add("hello");
list.Add("world");
list.Add("foo");
list.Add("bar");
foreach (string word in list)
{
if (word == "world")
{
list.Remove("bar"); // Will not crash the foreach!
}
Console.WriteLine(word);
}
Output:
hello
world
foo
I have requirement in which I have to back and fort with record. So I am using IEnumerator to that. But I can move forward by movenext but there no way to move back
Here's one way you could wrap an IEnumerator<T>, by capturing its contents in a List<T> as it moves along:
public interface ITwoWayEnumerator<T> : IEnumerator<T>
{
bool MovePrevious();
}
public class TwoWayEnumerator<T> : ITwoWayEnumerator<T>
{
private IEnumerator<T> _enumerator;
private List<T> _buffer;
private int _index;
public TwoWayEnumerator(IEnumerator<T> enumerator)
{
if (enumerator == null)
throw new ArgumentNullException("enumerator");
_enumerator = enumerator;
_buffer = new List<T>();
_index = -1;
}
public bool MovePrevious()
{
if (_index <= 0)
{
return false;
}
--_index;
return true;
}
public bool MoveNext()
{
if (_index < _buffer.Count - 1)
{
++_index;
return true;
}
if (_enumerator.MoveNext())
{
_buffer.Add(_enumerator.Current);
++_index;
return true;
}
return false;
}
public T Current
{
get
{
if (_index < 0 || _index >= _buffer.Count)
throw new InvalidOperationException();
return _buffer[_index];
}
}
public void Reset()
{
_enumerator.Reset();
_buffer.Clear();
_index = -1;
}
public void Dispose()
{
_enumerator.Dispose();
}
object System.Collections.IEnumerator.Current
{
get { return Current; }
}
}
Then I would expose this kind of enumerator using an extension method:
public static class TwoWayEnumeratorHelper
{
public static ITwoWayEnumerator<T> GetTwoWayEnumerator<T>(this IEnumerable<T> source)
{
if (source == null)
throw new ArgumentNullExceptions("source");
return new TwoWayEnumerator<T>(source.GetEnumerator());
}
}
Note that this is definitely overkill if the collection you're dealing with is already an indexed collection such as a T[] or a List<T>. It makes more sense for scenarios such as when you're enumerating over a sequence that isn't already in a conveniently indexed form and you want to be able to go backwards as well as forwards.
The IEnumerator (and IEnumerator<T>) interfaces only implement a forward only enumerator. You'll need to make your own class or interface if you want to allow bi-directional iteration through your collection.
You can't go backwards with IEnumerator. Either suck the entire set into a List or cache the current element on each pass through the loop, so it's available to the next pass.