/// <summary> /// Get value synchronouslym, if factory is async then factory is run in a background task. /// </summary> public Typename GetValue() { // shortcut if (_isValueCreated) { return(_value); } // if we're here there is no value.. yet, synchronize! _lock.Run(() => { // check again, maybe it was created if (_isValueCreated) { return; } // sync factory if (_factory != null) { _value = _factory(); // destroy fields that are not needed anymore _factory = null; } // async factory if (_asyncFactory != null) { // yes this blocks the thread, you called the sync version // but it does it on a background thread _value = _asyncFactory().Result; // destroy fields that are not needed anymore _asyncFactory = null; } _isValueCreated = true; }); return(_value); }
public void ByDefaultOnlyOneThreadCanEnter() { int counter = 0; var criticalSection = new AsyncLazy.AsyncLock(); ; var threads = Enumerable.Range(1, 10).Select(n => new Thread(() => criticalSection.Run(() => { counter++; counter.Should().Be(1); counter--; }))).ToList(); threads.ForEach(thread => thread.Start()); threads.ForEach(thread => thread.Join()); counter.Should().Be(0); }