We’re rewarding the question askers & reputations are being recalculated! Read more.
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....


13

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); }); } ...


11

Some suggestions: The trailing slash in the mkdir command is redundant. $(…) is preferred over backticks for command substitution. Why use seq in one command? They both do the same loop, so you might as well use {1..100} in both places. Semicolons are unnecessary in the vast majority of cases. Simply use a newline to achieve the same separation between ...


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)....


9

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()) { ...


5

A few observations off the top of my head cerrMutex is unused, and should be removed if not needed. mapMutex is used to guard a static std::map but is itself a regular class member variable. That suggests it probably isn't guarding the map against concurrent access. This is probably a bug. This seems like a fairly heavyweight tool. The uses of maps and ...


5

startTimer() The time package provides timers natively. So rather than using a call to time.Sleep(), you can use time.NewTimer(). Use fmt.Printf() rather than fmt.Println() for printing formatted strings. func startTimer(seconds int) { time.Sleep(time.Duration(seconds) * time.Second) fmt.Println("Time is up! You got ", points, " points") os....


5

The thing is, even so, standard grep still gets results faster by an amount of 60 % less processing time For more information on what makes GNU grep fast, read this by the original author. Here is some feedback on writing idiomatic Go. Lines Your code is oddly formatted. It is very uncommon to have empty lines everywhere. In your code, empty lines more ...


5

I think you'll find that inotify has problems of its own and that you're already on the right path. The approach I'd use: get this working the way you want, then run it in a loop while your wget runs, removing successful files as it goes. If you're concerned about polling overhead (I wouldn't be: the size of the directory should remain manageable so ...


4

Raising events inside of a lock is a code smell. Locks should be short lived as possible. Plus since, maybe today, you know what the events will do that doesn't mean in the future they won't change. Having a long processing event could make this a bottle neck or if an event also subscribed and wanted to update the collection has the potential for a ...


4

Rather than writing something custom, you could use the TLP Dataflow library. public static Task ForEachAsync<TSource>( this IEnumerable<TSource> items, Func<TSource, Task> action, int maxDegreesOfParallelism) { var actionBlock = new ActionBlock<TSource>(action, new ExecutionDataflowBlockOptions { ...


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 ...


4

Using GNU Parallel you code will look something like this: #!/usr/bin/env bash export script="path_to_python_script" doit() { i="$1" j="$2" $script -args_1 "$i" $script -args_1 "$i" -args_2 value -args_3 value } export -f doit parallel --resume --results data/file_{1}-{2}.txt doit ::: {1..100} ::: {1..100} In your original code if one ...


4

System.out.println(sex + " using bathroom. Current employees in bathroom = " + size); This line is not protected by lock, so it is possible that size can change before the output is generated. For example, if two 'M' arrive simultaneously, you could get as output: M using bathroom. Current employees in bathroom = 2 M using bathroom. Current employees in ...


3

Before we comment on the speed issue, perhaps we should talk about the multithread correctness of step(from:to:). You are referencing memory and index. You appear to be updating the same memory from all of your threads. That is not thread-safe. Your don’t want multiple threads updating the same memory reference. If you temporarily turn on the thread ...


3

Full code import (...) Please include your full code next time. This should instead be: import ( "database/sql" "errors" "fmt" "io/ioutil" "log" "net/http" "os" "path/filepath" "sync" "time" ) You also have item.toString(), but this is nowhere defined. I changed it to: fmt.Println(item) Scope connectionString ...


3

Nothing too exciting to say, but having spent some time looking through the code, thought I might as well post something: Code Separation I'd be compelled to separate the LZ77 FindMatches logic from the other logic; I would want as little interface between these as possible (e.g. HashTable should not be available to the other thread). I'd also want to ...


3

template< typename T, typename _TMtx, Get off the standard library's lawn! _Ugly names are reserved to the implementation. template<typename> class _TLock, template<typename> class _TMutLock > class lock_wrap_impl { template<typename W> using mimic_unique = typename std::conditional< std::...


3

if line := bf.Text(); (reg.Match([]byte(line)) && !inverseSearch) || (!reg.Match([]byte(line)) && inverseSearch) { As in other C-like languages, golang evaluates binary logical operators conditionally left-to-right. As written, the program is often going to evaluate the reg.Match() twice, because it appears twice and in each subexpression it ...


3

Readability Use keyword var any time that the initialization of the variable clearly tells what the variable represents. Avoid abbreviations in variable names. var messageQueue = new MessageQueue(queue); var semaphore = new SemaphoreSlim(15, 15); Configuration Avoid hard-coded settings: var semaphore = new SemaphoreSlim(15, 15); Make use of a pattern ...


3

The most expensive operation you're performing is calculating a^(rk) every iteration. Since you are doing this in a loop and increasing the exponent by a constant amount each iteration (k), you can replace the exponentiation with a multiplication. This makes your concurrent task function look like this: go func(receiver chan int64, rGiven, k int64) {...


3

/*9*/ template<class Alloc, class = std::enable_if_t<std::uses_allocator_v<Container, Alloc>>> BlockingQueue(const BlockingQueue& other, const Alloc& alloc) : queue_(alloc) { auto lock{std::scoped_lock(other.mutex_)}; queue_ = other.queue_; } This doesn't look quite right. queue_ = other.queue; may cause the ...


3

Foreword I appreciate you taking the effort to edit your question time and again to clarify your goal. At first, I thought you were making a synchronous task scheduler using whatever thread is available at any given time, which would have been really cool as well! In fact, your smartly designed API could be augmented to become one if you allow: chaining ...


3

For quote-word-count, there's a few things to note. I think this is a good use of ->>. Personally, I would have started the threading with (range quote-count) instead of splitting that though. From my experience, needlessly elongating the thread call just hurts readability. I also recommend maintaining the same type of object being threaded all the ...


2

There's no need to use synchronize for readers, as you are acquiring the lock for readCount++ and readCount--. One drawback in your code is the starvation for writers. The first reader has acquired writeLock, and so subsequent readers will keep on coming and will not let readCount become 0. So any waiting writers will always wait for writeLock to be ...


2

Task Parallel Library (TPL) I believe you are reinventing the wheel here. TPL provides numerous ways of synchronizing tasks. For instance, it allows you to: create a task scheduler from current synchronization context or to start a task on a specified task scheduler. All you need to do is create a custom synchronization context (.NET Core no longer ...


2

Usability (WPF Only) I've read in comments on a different answer that you were going to wrap private readonly System.Windows.Threading.Dispatcher _context; in some kind of custom dispatcher. Don't do this! Your class depends on a WPF dispatcher, hence it's use cases are limited to WPF. You should use a TaskScheduler instead. If you create your list in the ...


2

On Threading lockfree code is rarely easy to understand. I would beg to differ. It usually just hides the complex situations. On Spin Locks. Spin locks are generally not a good idea. You should be really sure that a thread caught in a spin lock will escape quickly (otherwise you are going to melt your processor). But you mitigate the problem by using ...


2

A couple of generic good practices are Try to avoid using global variables(You can pass wg, ch & errItems as arguments to function) Single Responsibility function(A function should do only once task. Makes it easy to test.) As far as possible pass dependencies as variables or using dependency injection etc. Specific to this snippet you can: Pass ...


2

Task.WhenAll also accepts Enumerable<Task> as argument. So your lines with tasks can be simplified: var tasks = source.Select(x => Task.Run(() => body(s), token)); try { await Task.WhenAll(tasks).ConfigureAwait(false); token.ThrowIfCancellationRequested(); } catch { // find the error(s) that might have happened. var errors = ...


Only top voted, non community-wiki answers of a minimum length are eligible