The Stack Overflow podcast is back! Listen to an interview with our new CEO.
52

Short and clean using null-coalescing operator: public async Task<WebData> GetDataByIdAsync(GetDataById input) { return await DataAccess.FindDataById<TwitterData>(input.Id)?? await DataAccess.FindDataById<FacebookData>(input.Id)?? await DataAccess.FindDataById<LinkedinData>(input.Id); }


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


21

Just fire the task without async/await. private void InitMethod(ServiceControl serviceControl) { if (serviceControl != null) { Task.Factory.StartNew(() => serviceControl.Execute()); } } In a proper F&F task all exception handling (including a final catch, logging, notifications) is done by the task itself, so you don't need ...


21

Use the return pattern: public async Task<WebData> GetDataByIdAsync(GetDataById input) { var twitterData = await DataAccess.FindDataById<TwitterData>(input.Id); if (twitterData != null) { return twitterData; } var facebookData = await DataAccess.FindDataById<FacebookData>(input.Id); if (facebookData != ...


18

There are several ways to achieve what you're after and it depends on whether you want the results drip fed to you as they're available or whether you're happy to have them all in one bang. The way you've implemented your method gives it all in one bang - which is fine. A shorter implementation could be public static async Task<IEnumerable<T>> ...


18

Well, first questions is: why don't you use MVVM? Contents of your App class look like something that should be implemented on model/view model level. This looks like a lot of copy-pasting private void Blue_MouseDown(object sender, MouseButtonEventArgs e) { OnSimonButtonClicked(SimonButton.Blue); e.Handled = true; } private void Yellow_MouseDown(...


16

The things to consider when it comes to async event handlers are: Exceptions thrown for the handler might be rethrown on the UI SynchronizationContext, which usually crashes the application. After you raise the event, the handlers won't be completed yet. The execution of a handler might be interleaved with the execution of the code after the raising and ...


15

Magic numbers, you have at least one of them in class App: private async Task PlaySequence() you should extract this to either a constant or better to a property, so that the speed, aka less sleep, can be adjusted. I don't see the point of the _seed variable. Yeah, I know why you use it, but it just forces you, each time the GenerateSequence() method is ...


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


12

Is it ok to have an async void method? Referencing Async/Await - Best Practices in Asynchronous Programming As already stated in the OP async void should be avoided as much as possible. The one exception to that rule being for event handlers, which can be the loophole to achieving the desired behavior while still having the ability to catch and handle ...


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


10

I need to delete a file when an error occurs during loading it. In other words: Happy path: Load a file Move on Unhappy path: Load a file, exception is thrown Delete the file Move on Exceptional path: Load a file, exception is thrown Delete the file, exception is thrown Handle exception, move on From these points, it appears we'd need a task that ...


10

Initial observation is that you should avoid async void like private async void start() { //... } except for event handlers. Reference Async/Await - Best Practices in Asynchronous Programming Luckily there is one for the start button. So start by refactoring start to be proper async private async Task start() { //... } and awaiting it in the ...


10

Quick Review An API like this, dealing with thread-sensitive operations, requires time and effort to test and review rigorously. When I will find this time, I will do a thorough review. But here are some things I notice right off the bat. CommMemoryDisposedException should inherit from ObjectDisposedException. This way, consumers can handle your exception ...


9

Just a few quick remarks (for now): vbNullString is a remnant of VB6 (which I think would be under the Microsoft.VisualBasic.Constants namespace), and used to be a null string pointer often confused with "", an empty string. In VB.NET vbNullString is Nothing, so when you do this: If targetFolder = vbNullString Then You're actually verifying whether ...


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


8

There's something odd about your constructors - normally chained constructors call the constructor with the most parameters, not the other way around: public ProsperApi(string username, string password, string baseUrl) : this(username, password) public ProsperApi(string username, string password) Should be: public ProsperApi(string username, string ...


8

Nesting. You can reduce nesting by stacking the using blocks, like this: using (var connection = new SqlConnection(connectionString)) using (var command = new SqlCommand(cmdText, connection)) { try { command.CommandType = cmdType; command.Parameters.AddRange(commandParameters); connection.Open(...


8

The first thing that needs to be addressed is the indentation and the spacing, because that's the real issue here. You should line your braces with the start of the line above it, like so : if() { } Instead of : if(reached == 0) { // Yay it completed. } While we're at it, this code is weird : if(reached == 0) { // Yay it completed. } ...


8

One drawback I can think of this way of logging is that (correct me if I'm wrong) it is lazy. That's to say, until the root Op object is Disposed, all of the log items are kept in memory. This means that you are relying entirely on the functionality of the topmost using statement to ensure the log gets properly written somewhere. If due to some external ...


7

You are using async/await absolutely correctly, that's how they were supposed to be used. Please note that from this code it's hard to tell whether the method will return the Task immediately, since it will be waiting synchronously for rasterize method to return the Task, and thus the answer depends on the implementation of rasterize. As a side note - you ...


7

Code looks good, I like this IoC style. 3 points to your consideration: You should catch an AggregateException over await. I wouldn't bother passing a logger to a serializer - that's none of his business. Let the serializer throw if he's not happy. Fix some typo in names and messages ("Deserialse" and so). I somewhat doubt the whole concept of async ...


7

Your first mistake is to do something with async that is CPU bound. That is not what you use async code for, async code is good for IO bound work, not CPU bound work. That you have to use Task.Yield() is indeed a indication you are using async code wrong. You should probably switch to the TPL library, and call something like Parallel.Invoke(() => ...


7

If it's really just removing an item from a dictionary (and not e.g. doing synchronous file IO), then Alternative 1 is the best. When you're using async for scalability (e.g. in ASP.NET), using Task.Run() like this won't help you (since the number of threads used stays the same), it will only hurt you a bit (since Task.Run() has some overhead). When you're ...


7

Nested ternary conditionals are ugly. Ternary conditionals nested three deep are ugly to the third power: Status = _moduleStates.Values.Any(value => value == ParserState.Error) ? ParserState.Error : _moduleStates.Values.Any(value => value == ParserState.Parsing) ? ParserState.Parsing : _moduleStates.Values.Any(value => ...


7

Just wanted to add that you may want to consider using Polly instead of rolling your own retry mechanism - this is a library built specifically for this kind of retry mechanism (as well as many more complicated scenarios). Using Polly would look something like the following. Note that I have renamed the attempts parameter to retryAttempts to make it clear ...


6

As the latecomer to the party, I'll take it from V3... First, async void should only be used for event handlers. I'd much rather see Start return a Task representing the listening loop. For a simple example, you don't need to do any cleanup at all. Once your app exits, the OS will clean up after it. Doing cleanup just before application exit is just a ...


6

At first I tried to make it completely lock-less, but it turned out to be impossible. This implementation contains a lock however the lock isn't an instance wide. It may shock you to hear that lock-free code may be slower than code using locking. Lock-free code is usually longer and is definitely much more complex. You should not attempt to write lock-free ...


6

I will look at this again in a couple of days or maybe even later today, but here is something I saw right at the end of the question WebSocketReceiveResult response; while (true) { response = await _socket.ReceiveAsync(new ArraySegment<byte>(temporaryBuffer), CancellationToken....


6

I'd prefer the first method because it's making more efficient use of resources (provided the async methods you call are really async and not just wrappers around synchronous methods) and it also looks cleaner. To quote from this MSDN blog: ... the only asynchronous methods that should be exposed are those that have scalability benefits over their ...


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