私は、並行プログラミングを始めています。おそらく私の問題は非常に一般的ですが、私はそれの良い名前を見つけることができないので、私はそれをGoogleすることはできません。関数のインスタンスが1つしか実行されていないことを確認しますか?
私はMVVMパターンを適用しようとするC++ UWPアプリケーションを持っていますが、パターンやUWPも関係ないと思います。私は具体的な実装を提供しますが、それはこの議論には関係ありませんが、もちろん
struct IService
{
virtual task<int> Operation() = 0;
};
:
まず、私が操作を公開するサービス・インターフェースを持っています。この操作は長時間実行される可能性があります。つまり、HTTP要求を行います。
それから私は(再び、無関係な詳細は省略)サービスを使用するクラスを持っている:私はコルーチンを使用
class ViewModel
{
unique_ptr<IService> service;
public:
task<void> Refresh();
};
:
task<void> ViewModel::Refresh()
{
auto result = co_await service->Operation();
// use result to update UI
}
リフレッシュ機能は、タイマーで毎分起動され、またはユーザーの要求に応じて私が欲しいのは、新しい操作が開始または要求されたときにリフレッシュ操作がすでに進行中で、次に2番目の操作を中止し、最初の操作が完了するまで待つ(またはタイムアウトする)ことです。言い換えれば、私はすべてのコールをリフレッシュにキューイングしたくありません。コールがすでに進行中の場合は、次のタイマーティックまでコールをスキップすることをお勧めします。 (おそらく非常にナイーブ)
私の試みでした:それは違いはありませんように私は、上記のコードの行をコメントアウト:
mutex refresh;
task<void> ViewModel::Refresh()
{
unique_lock<mutex> lock(refresh, try_to_lock);
if (!lock)
{
// lock.release(); commented out as harmless but useless => irrelevant
co_return;
}
auto result = co_await service->Operation();
// use result to update UI
}
編集オリジナルのポストの後。問題はまだ同じです。
もちろん、アサーションが失敗します:unlock of unowned mutex
。私は問題がmutex
によってunique_lock
デストラクタによってunlock
であると推測します。これはコルーチンの継続と別のスレッド(最初はロックされていたものを除く)で起こります。
のVisual C++ 2017
@WhozCraig、私は試していませんが、私はどのような提案にも開放されています - あなたはコード例を挙げられますか? –
本当に素朴な解決策: 'std :: atomic running'。 –
MSalters
あなたはロックされていないことが分かっているロックを解放しようとしているという事実については問題があると思いませんか? – UKMonkey