I just enter parallel programming. Most likely, my problem is very common, but since I canβt find a good name for her, I canβt use it.
I have a C ++ UWP application where I try to apply the MVVM pattern, but I assume that the pattern or even UWP does not matter.
Firstly, I have a service interface that provides an operation:
struct IService { virtual task<int> Operation() = 0; };
Of course, I provide a specific implementation, but this is not relevant to this discussion. The operation is potentially long running: it makes an HTTP request.
Then I have a class that uses the service (again, irrelevant data is omitted):
class ViewModel { unique_ptr<IService> service; public: task<void> Refresh(); };
I use coroutines:
task<void> ViewModel::Refresh() { auto result = co_await service->Operation();
The update function is activated by the timer every minute or in response to a user request. I want: if the update operation is already running when a new one is starting or is being requested, open the second one and wait until the first one finishes (or time out). In other words, I don't want to queue all Refresh calls - if the call is already in progress, I prefer to skip the call until the next timer.
My attempt (possibly very naive):
mutex refresh; task<void> ViewModel::Refresh() { unique_lock<mutex> lock(refresh, try_to_lock); if (!lock) {
Edit after the original post: I commented out the line in the code snippet above, as this does not make any difference. The problem remains the same.
But, of course, the statement fails: unlock of unowned mutex . I assume that the problem is the unlock of mutex from the unique_lock destructor, which occurs in the continuation of the coroutine and in another thread (except the one that was originally blocked).
Using Visual C ++ 2017.