New answers tagged

-1

You can use the Golang Concurrency Manager goccm to limit the maximum number of goroutines to run concurrently: Example: package main import ( "fmt" "goccm" "time" ) func main() { // Limit 3 goroutines to run concurrently. c := goccm.New(3) for i := 1; i <= 10; i++ { // This function have to call before any goroutine ...


8

If you modify the AsyncDictionary while enumerating its keys/values it throws InvalidOperationException (if the backing dictionary is a Dictionary). var numbers = new AsyncDictionary<int, int>(); foreach(var number in Enumerable.Range(1, 1000)) { await numbers.AddAsync(number, number); } foreach(var number in await numbers.GetKeysAsync()) { ...


11

It's pretty hard to break something that uses a global lock around everything. So this seems pretty thread-safe. But that doesn't answer the question of why you'd want to use this. Asynchronous calls are useful for things that take a long time, particularly if you can delegate the "waiting" to some low-level event based solution (HTTP requests for example)....


24

The reason why there is no async API for a dictionary is, that all operations on a dictionary are so fast, that there is no need for asynchronicity. For concurrent scenarios there is the thread safe variant - the ConcurrentDictionary. Adding an async API to these dictionaries has absolutely zero value. Rather it increases complexity and reduces performance....


11

Threading Design Your implementation has a very intrusive lock for all read and write operations, using the SemaphoreSlim with max concurrency 1. try { await _semaphoreSlim.WaitAsync()// <- both read/write operations acquire single mutex return await Task.Run(async () => { return await func(_dictionary, keyValuePair); }); } ...


1

Blocking code in a loop You are starting your tasks asynchronously.. Task.Factory.StartNew(() only to block synchronously inside the loop.. allLinks.Add(task.Result.ToList()); resulting in sequentially starting and awaiting the intermediate results for each cycle in the loop. foreach (string rootUrl in rootUrls) { // .. code ...


4

Dispose the scheduler gracefully As you mentioned, you lack proper disposal functionality. void Run() { while (!m_disposed) { var task = m_taskQueue.Take(); Debug.Assert(TryExecuteTask(task)); } } The first issue is that bool m_disposed is not marked as volatile. This means that this variable is subject to optimisations that could ...


Top 50 recent answers are included