Qt-async рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╡рд┐рдЬреЗрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реА

рд╕рднреА рдХреЛ рд╢реБрдн рджрд┐рдиред рдореИрдВ рдЕрдкрдиреЗ qt-async рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝реА рдмрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рдХреЛ рджрд┐рд▓рдЪрд╕реНрдк рдпрд╛ рдЙрдкрдпреЛрдЧреА рднреА рд▓рдЧреЗред

рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд░реЛрдЬрдорд░реНрд░рд╛ рдХреЗ рдЬреАрд╡рди рдореЗрдВ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕реА рдФрд░ рдорд▓реНрдЯреАрдереНрд░реЗрдбрд┐рдВрдЧ рдХреЛ рдЧрдВрднреАрд░рддрд╛ рд╕реЗ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдХрдИ рдЖрдзреБрдирд┐рдХ рднрд╛рд╖рд╛рдУрдВ рдФрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЙрдкрдпреЛрдЧ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдХрд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред C ++ рднрд╛рд╖рд╛ рднреА рдзреАрд░реЗ-рдзреАрд░реЗ рдЗрд╕ рджрд┐рд╢рд╛ рдореЗрдВ рдЖрдЧреЗ рдмрдврд╝ рд░рд╣реА рд╣реИ - std :: thread, std :: рд╡рд╛рджрд╛ / рднрд╡рд┐рд╖реНрдп рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ рд╣реИ, рд╡реЗ coroutines рдФрд░ рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ рдореЗрдВ рд▓рд╛рдиреЗ рд╡рд╛рд▓реЗ рд╣реИрдВред рдХреНрдпреВрдЯреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рднреА рдкреАрдЫреЗ рдирд╣реАрдВ рд░рд╣рддреА рд╣реИ, рдЗрд╕рдХреЗ рдПрдирд╛рд▓реЙрдЧреНрд╕ рдХреНрдпреВрдереНрд░реЗрдб, рдХреНрдпреВрдЖрд░рдиреНрдпреВрдиреЗрдмрд▓, рдХреНрдпреВрдереНрд░реЗрдбрдкреВрд▓, рдХреНрдпреВрдлреНрдпреВрд╡рди рдЗрддреНрдпрд╛рджрд┐ рдХреА рдкреЗрд╢рдХрд╢ рдХрд░рддреА рд╣реИред рдЙрд╕реА рд╕рдордп, рдореБрдЭреЗ Qt рдореЗрдВ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдЧреЗрдЯреНрд╕ рдирд╣реАрдВ рдорд┐рд▓рд╛ (рд╢рд╛рдпрдж рдореИрдВ рдмреБрд░реА рддрд░рд╣ рд╕реЗ рд╕рд╣реА рджрд┐рдЦ рд░рд╣рд╛ рдерд╛, рдЕрдЧрд░ рдореИрдВ рдЧрд▓рдд рд╣реВрдВ рддреЛ рд╕рд╣реА)ред

рдЗрд╕рд▓рд┐рдП, рдореИрдВрдиреЗ рдХрдореА рдХреЗ рд▓рд┐рдП рдмрдирд╛рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рд╡рд┐рдЬреЗрдЯ рдХреЛ рд╕реНрд╡рдпрдВ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ред рдмрд╣реБрдЖрдпрд╛рдореА рд╡рд┐рдХрд╛рд╕ рдПрдХ рдЬрдЯрд┐рд▓, рд▓реЗрдХрд┐рди рджрд┐рд▓рдЪрд╕реНрдк рд╡реНрдпрд╡рд╕рд╛рдп рд╣реИред

рд╡рд┐рдЬреЗрдЯ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдЖрдЧреЗ рдмрдврд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рдЙрд╕ рдореЙрдбрд▓ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдЗрд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдВрдбреЛ рдХреЗ рд░реВрдк рдореЗрдВ рдкреЗрд╢ рдХрд░реЗрдЧреАред рдЕрдкрдиреЗ рд╕рдмрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рдореЗрдВ, рд╡рд┐рдЬреЗрдЯ рдХрд╛ рд╕рдВрдЪрд╛рд▓рди рдореБрдЭреЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд▓рдЧрддрд╛ рд╣реИ: рдХрд┐рд╕реА рд╕рдордп рдореЗрдВ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдпрд╛ рд╕рд┐рд╕реНрдЯрдо рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдСрдкрд░реЗрд╢рди рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рд╡рд┐рдЬреЗрдЯ рдСрдкрд░реЗрд╢рди рдХреА рдкреНрд░рдЧрддрд┐ рдпрд╛ рдСрдкрд░реЗрд╢рди рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рд╕рдВрдХреЗрдд рджрд┐рдЦрд╛рддрд╛ рд╣реИред рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдкрд╛рд╕ рдСрдкрд░реЗрд╢рди рдХреЛ рд░рджреНрдж рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдСрдкрд░реЗрд╢рди рджреЛ рддрд░рд╣ рд╕реЗ рдкреВрд░рд╛ рд╣реЛрддрд╛ рд╣реИ: рдпрд╛ рддреЛ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реБрдИ рдФрд░ рд╣рдорд╛рд░рд╛ рд╡рд┐рдЬреЗрдЯ рдЗрд╕реЗ рджрд┐рдЦрд╛рддрд╛ рд╣реИ, рдпрд╛ рд╡рд┐рдЬреЗрдЯ рд╕рдлрд▓ рдСрдкрд░реЗрд╢рди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рджрд┐рдЦрд╛рддрд╛ рд╣реИред

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдорд╛рд░рд╛ рдореЙрдбрд▓ рддреАрди рд░рд╛рдЬреНрдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдореЗрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ:

  1. рдкреНрд░рдЧрддрд┐ - рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдСрдкрд░реЗрд╢рди рдЬрд╛рд░реА рд╣реИ
  2. рддреНрд░реБрдЯрд┐ - рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдСрдкрд░реЗрд╢рди рд╡рд┐рдлрд▓
  3. рдорд╛рди - рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдСрдкрд░реЗрд╢рди рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкреВрд░рд╛ рд╣реБрдЖ

рдкреНрд░рддреНрдпреЗрдХ рд░рд╛рдЬреНрдп рдореЗрдВ, рдореЙрдбрд▓ рдХреЛ рд╕рдВрдмрдВрдзрд┐рдд рдбреЗрдЯрд╛ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ AsyncValue рдореЙрдбрд▓ рдХрд╣рд╛ред рдпрд╣ рдзреНрдпрд╛рди рд░рдЦрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдСрдкрд░реЗрд╢рди рд╕реНрд╡рдпрдВ рд╣рдорд╛рд░реЗ рдореЙрдбрд▓ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдХреЗрд╡рд▓ рдЕрдкрдиреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрджрд▓рддрд╛ рд╣реИред рдпрд╣ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ AsyncValue рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рд╕реА рднреА рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЙрдкрдпреЛрдЧ рдкреИрдЯрд░реНрди рдХрд╛ рдЕрд╡рд▓реЛрдХрди рдХрд░ рд░рд╣рд╛ рд╣реИ:

  1. рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдСрдкрд░реЗрд╢рди рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ, AsuncValue рдХреЛ рдкреНрд░рдЧрддрд┐ рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВ
  2. рдЕрдВрдд рдореЗрдВ - рдпрд╛ рддреЛ рддреНрд░реБрдЯрд┐ рдпрд╛ рдореВрд▓реНрдп рдореЗрдВ, рдСрдкрд░реЗрд╢рди рдХреА рд╕рдлрд▓рддрд╛ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ
  3. рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ, рдСрдкрд░реЗрд╢рди рдХреЗ рджреМрд░рд╛рди, рдЖрдк рдкреНрд░рдЧрддрд┐ рдбреЗрдЯрд╛ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕реНрдЯреЙрдк рдлреНрд▓реИрдЧ рдХреЛ рд╕реБрди рд╕рдХрддреЗ рд╣реИрдВ рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдкрд╛рд╕ рдСрдкрд░реЗрд╢рди рдХреЛ рд░реЛрдХрдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рд╣реИред

рдпрд╣рд╛рдБ рдПрдХ рдпреЛрдЬрдирд╛рдмрджреНрдз рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ QRunnable рд╣реИ:

class MyRunnable : public QRunnable { public: MyRunnable(AsyncValue& value) : m_value(value) {} void run() final { m_value.setProgress(...); // do calculation if (success) m_value.setValue(...); else m_value.setError(...); } private: AsyncValue& m_value; } 

Std рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рдпреЛрдЬрдирд╛ :: рдзрд╛рдЧрд╛:

 AsyncValue value; std::thread thread([&value] () { value.setProgress(...); // do calculation if (success) value.setValue(...); else value.setError(...); }); 

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдорд╛рд░реА рдХрдХреНрд╖рд╛ рдХрд╛ рдкрд╣рд▓рд╛ рд╕рдВрд╕реНрдХрд░рдг рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:

 template <typename ValueType_t, typename ErrorType_t, typename ProgressType_t> class AsyncValue { public: using ValueType = ValueType_t; using ErrorType = ErrorType_t; using ProgressType = ProgressType_t; // public API private: QReadWriteLock m_lock; std::variant<ValueType, ErrorType, ProgressType> m_value; }; 

рд╣рд░ рдХреЛрдИ рдЬреЛ рдЙрди рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рдЖрддрд╛ рд╣реИ рдЬреЛ рдорд▓реНрдЯреАрдереНрд░реЗрдбрд┐рдВрдЧ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВ, рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдРрд╕реА рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рдПрдирд╛рд▓реЙрдЧреНрд╕ рд╕реЗ рдЕрд▓рдЧ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рд╡реЗрдХреНрдЯрд░ рдореЗрдВ рдЖрдХрд╛рд░ () рдлрд╝рдВрдХреНрд╢рди рдмреЗрдХрд╛рд░ рдФрд░ рдЦрддрд░рдирд╛рдХ рд╣реИред рдЗрд╕рдХрд╛ рдкрд░рд┐рдгрд╛рдо рддреБрд░рдВрдд рдЕрдорд╛рдиреНрдп рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗрдХреНрдЯрд░ рдХреЛ рджреВрд╕рд░реЗ рдзрд╛рдЧреЗ рдореЗрдВ рдкрд▓ рдореЗрдВ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

AsyncValue рд╡рд░реНрдЧ рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╡рд░реНрдЧ рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдбреЗрдЯрд╛ рдХреА рдПрдХ рдкреНрд░рддрд┐ рдЬрд╛рд░реА рдХрд░рдирд╛ рдорд╣рдВрдЧрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ ValueType / ErrorType / ProgressType рднрд╛рд░реА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЖрдВрддрд░рд┐рдХ рдбреЗрдЯрд╛ рдХрд╛ рд▓рд┐рдВрдХ рдЬрд╛рд░реА рдХрд░рдирд╛ рдЦрддрд░рдирд╛рдХ рд╣реИ - рдХрд┐рд╕реА рднреА рд╕рдордп рдпрд╣ рдЕрдорд╛рдиреНрдп рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдорд╛рдзрд╛рди рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╣реИ:

1. рдлрд╝рдВрдХреНрд╢рдВрд╕ рдПрдХреНрд╕реЗрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдБрдЪ рдкреНрд░рджрд╛рди рдХрд░реЗрдВ Access / AccessError / accessProgress, рдЬрд┐рд╕рдореЗрдВ lambdas рдкреНрд░рд╛рдкреНрдд рд╣реЛрддреЗ рд╣реИрдВ рдЬреЛ рд╕рдВрдмрдВрдзрд┐рдд рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

 template <typename Pred> bool accessValue(Pred valuePred) { QReadLocker locker(&m_lock); if (m_value.index() != 0) return false; valuePred(std::get<0>(m_value)); return true; } 

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЖрдВрддрд░рд┐рдХ рдореВрд▓реНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рдВрджрд░реНрдн рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд▓реЙрдХ рдХреЗ рддрд╣рдд рд╣реЛрддрд╛ рд╣реИред рдпрд╛рдиреА, рдПрдХреНрд╕реЗрд╕ рдХреЗ рд╕рдордп рд▓рд┐рдВрдХ рдЕрдорд╛рдиреНрдп рдирд╣реАрдВ рд╣реЛрдЧрд╛ред

2. рдПрдХреНрд╕реЗрд╕ рдбреЗрдЯрд╛ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ AsyncValue рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЖрдВрддрд░рд┐рдХ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдВрдХ рдХреЛ рдпрд╛рдж рд░рдЦ рд╕рдХрддрд╛ рд╣реИ, рдмрд╢рд░реНрддреЗ рдХрд┐ рд╡рд╣ рд░рд╛рдЬрдХреАрдп рд╕рдВрдХреЗрдд рдХреЗ рд▓рд┐рдП рд╕рджрд╕реНрдпрддрд╛ рд▓рд┐рдпрд╛ рд╣реЛ рдФрд░ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдмрд╛рдж рд╕рдВрдХреЗрдд рдХреЛ рдЗрд╕ рд▓рд┐рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рд╡рд╣ рдЕрдорд╛рдиреНрдп рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

рдРрд╕реА рд╢рд░реНрддреЛрдВ рдХреЗ рддрд╣рдд, AsyncValue рдЙрдкрднреЛрдХреНрддрд╛ рдХреЛ рд╣рдореЗрд╢рд╛ рд╡реИрдз рдФрд░ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдбреЗрдЯрд╛ рдПрдХреНрд╕реЗрд╕ рдХреА рдЧрд╛рд░рдВрдЯреА рджреА рдЬрд╛рддреА рд╣реИред рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдХреЗ рдХрдИ рдкрд░рд┐рдгрд╛рдо рд╣реИрдВ рдЬреЛ AsyncValue рд╡рд░реНрдЧ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдорд╛рд░реА рдХрдХреНрд╖рд╛ рдХреЛ рдПрдХ рд░рд╛рдЬреНрдп рдмрджрд▓рдиреЗ рдкрд░ рдПрдХ рд╕рдВрдХреЗрдд рднреЗрдЬрдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рд╕рд╛рде рд╣реА рдпрд╣ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╣реИред рд╣рдореЗрдВ рдПрдХ рдореВрд▓ Qt рд╡рд░реНрдЧ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛, рдЬрд╣рд╛рдВ рд╣рдо рдЙрд╕ рд╕рдВрдХреЗрдд рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рд╡рд┐рдЬреЗрдЯ рдЕрдкрдиреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдЧрд╛, рдФрд░ рдЬреЛ рд╕рднреА рдЗрдЪреНрдЫреБрдХ рд╣реИрдВ рд╡реЗ рдЖрдВрддрд░рд┐рдХ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдВрдХ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВрдЧреЗред

 lass AsyncValueBase : public QObject { Q_OBJECT Q_DISABLE_COPY(AsyncValueBase) signals: void stateChanged(); }; 

рджреВрд╕рд░реЗ, рд╕рд┐рдЧреНрдирд▓ рднреЗрдЬрдиреЗ рдХреЗ рдХреНрд╖рдг рдХреЛ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд╡рд░реБрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП (рддрд╛рдХрд┐ рд╕рднреА рдХреЛ рд╕рд┐рдЧреНрдирд▓ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рддрдХ AsyncValue рдирд╣реАрдВ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХреЗ) рдФрд░, рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЙрд╕ рд╕рдордп рдирдП рдФрд░ рдкреБрд░рд╛рдиреЗ рдбреЗрдЯрд╛ рдХреЗ рд╡реИрдз рд▓рд┐рдВрдХ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред рдХреНрдпреЛрдВрдХрд┐ рд╕рд┐рдЧреНрдирд▓ рднреЗрдЬрдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рдХреБрдЫ AsyncValue рдЙрдкрднреЛрдХреНрддрд╛ рдЕрднреА рднреА рдкреБрд░рд╛рдиреЗ рд▓рд┐рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЬреЛ рд╕рд┐рдЧреНрдирд▓ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рд╡реЗ рдирдП рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред

рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рдПрд╕рдЯреАрдбреА :: рд╕рдВрд╕реНрдХрд░рдг рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реИ рдФрд░ рд╣рдореЗрдВ рдЧрддрд┐рд╢реАрд▓ рдореЗрдореЛрд░реА рдореЗрдВ рдбреЗрдЯрд╛ рд╕реНрдЯреЛрд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рддрд╛рдХрд┐ рдирдП рдФрд░ рдкреБрд░рд╛рдиреЗ рдбреЗрдЯрд╛ рдХреЗ рдкрддреЗ рдЕрдкрд░рд┐рд╡рд░реНрддрд┐рдд рд░рд╣реЗрдВред

рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рд╡рд┐рд╖рдпрд╛рдВрддрд░ред

рдЖрдк AsyncValue рд╡рд░реНрдЧ рдХреЗ рдЕрдиреНрдп рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЧрддрд┐рд╢реАрд▓ рдЖрд╡рдВрдЯрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ:

  1. рдЙрдкрднреЛрдХреНрддрд╛рдУрдВ рдХреЛ рдХреЗрд╡рд▓ AsyncValue рдЖрдВрддрд░рд┐рдХ рдбреЗрдЯрд╛ рдХреА рдкреНрд░рддрд┐рдпрд╛рдВ рджреЗрдВред рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд▓рд┐рдЦрд╛ рдерд╛, рдпрджрд┐ рдбреЗрдЯрд╛ рдмрдбрд╝рд╛ рд╣реИ рддреЛ рдРрд╕рд╛ рд╕рдорд╛рдзрд╛рди рдЕрдзрд┐рдХ рдЙрдк-рд░реВрдкреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
  2. рдПрдХ рдХреЗ рдмрдЬрд╛рдп рджреЛ рд╕рдВрдХреЗрддреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ: StateWillChange / stateDidChangeред рдкрд╣рд▓реЗ рд╕рдВрдХреЗрдд рдкрд░ рдкреБрд░рд╛рдиреЗ рд▓рд┐рдВрдХ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрднреЛрдХреНрддрд╛рдУрдВ рдХреЛ рдЙрдкрдХреГрдд рдХрд░рдирд╛ рдФрд░ рджреВрд╕рд░реЗ рд╕рд┐рдЧреНрдирд▓ рдкрд░ рдирдП рд▓рд┐рдВрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ред рдпрд╣ рдпреЛрдЬрдирд╛, рдореБрдЭреЗ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ AsyncValue рдЙрдкрднреЛрдХреНрддрд╛рдУрдВ рдХреЛ рдЕрддреНрдпрдзрд┐рдХ рдкрд░реЗрд╢рд╛рди рдХрд░рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЬрдм AsyncValue рддрдХ рдкрд╣реБрдБрдЪ рд╕реЗ рд╡рдВрдЪрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдЙрдирдХреЗ рдкрд╛рд╕ рд╕рдордп рдЕрдВрддрд░рд╛рд▓ рд╣реЛрддрд╛ рд╣реИред

рд╕реЗрдЯрд╡реИрд▓реНрдпреВ рдлрдВрдХреНрд╢рди рдХрд╛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдпреЛрдЬрдирд╛рдмрджреНрдз рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

 void AsyncValue::setValue(...) {  m_lock            {   m_lock          m_lock   }  stateChanged       m_lock   }; 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП m_lock рд▓реЙрдХ рдХреЛ рдмрдврд╝рд╛рдиреЗ рдФрд░ рдЗрд╕реЗ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, QReadWriteLock рд╡рд░реНрдЧ рдореЗрдВ рдРрд╕рд╛ рдХреЛрдИ рд╕рдорд░реНрдерди рдирд╣реАрдВ рд╣реИред рдЖрдк QMutex / QReadWriteLock рдХреА рдПрдХ рдЬреЛрдбрд╝реА рдХреЗ рд╕рд╛рде рд╡рд╛рдВрдЫрд┐рдд рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣рд╛рдБ AsyncValue рд╡рд░реНрдЧ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ, рдЬреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреЗ рдХрд░реАрдм рд╣реИ:

 //   AsyncValue enum class ASYNC_VALUE_STATE { VALUE, ERROR, PROGRESS }; Q_DECLARE_METATYPE(ASYNC_VALUE_STATE); //        class AsyncValueBase : public QObject { Q_OBJECT Q_DISABLE_COPY(AsyncValueBase) signals: void stateChanged(ASYNC_VALUE_STATE state); protected: explicit AsyncValueBase(ASYNC_VALUE_STATE state, QObject* parent = nullptr); //     PromoteToWriteLock/DemoteToReadLock QMutex m_writeLock; QReadWriteLock m_contentLock; //   ASYNC_VALUE_STATE m_state; }; template <typename ValueType_t, typename ErrorType_t, typename ProgressType_t> class AsyncValueTemplate : public AsyncValueBase { //  struct Content { std::unique_ptr<ValueType_t> value; std::unique_ptr<ErrorType_t> error; std::unique_ptr<ProgressType+t> progress; }; Content m_content; public: using ValueType = ValueType_t; using ErrorType = ErrorType_t; using ProgressType = ProgressType_t; //    template <typename... Args> void emplaceValue(Args&& ...arguments) { moveValue(std::make_unique<ValueType>(std::forward<Args>(arguments)...)); } //    void moveValue(std::unique_ptr<ValueType> value) { //       Content oldContent; //   emplaceXXX/moveXXX    QMutexLocker writeLocker(&m_writeLock); { //       QWriteLocker locker(&m_contentLock); //      oldContent = std::move(m_content); //    m_content.value = std::move(value); //    m_state = ASYNC_VALUE_STATE::VALUE; //     } //   emitStateChanged(); //    emplaceXXX/moveXXX  //    } //   value void emplaceError(Args&& ...arguments); void moveError(std::unique_ptr<ErrorType> error); void emplaceProgress(Args&& ...arguments); void moveProgress(std::unique_ptr<ProgressType> progress); template <typename Pred> bool accessValue(Pred valuePred) { //     QReadLocker locker(&m_contentLock); //    if (m_state != ASYNC_VALUE_STATE::VALUE) return false; //      valuePred(*m_content.value); //     return true; } //  accessValue bool accessError(Pred errorPred) bool accessProgress(Pred progressPred) }; 

рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдердХреЗ рд╣реБрдП рдФрд░ рдЦреЛрдП рдирд╣реАрдВ рд╣реИрдВ, рд╣рдо рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВред

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХреНрд╕реЗрд╕рдПрдХреНрд╕рдПрдХреНрд╕рдПрдХреНрд╕ рдлрд╝рдВрдХреНрд╢рди рд╣реИрдВ рдЬреЛ рддрдм рддрдХ рдЗрдВрддрдЬрд╛рд░ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рдЬрдм рддрдХ рдХрд┐ рдЕрд╕рд┐рдВрдХрд╡реИрд▓реНрдпреВ рд╕рдВрдмрдВрдзрд┐рдд рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдмрд╕ рдЭреВрдареЗ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдХрднреА-рдХрднреА рдЙрдкрдпреЛрдЧреА рд░реВрдк рд╕реЗ рддрдм рддрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрддрд╛ рд╣реИ рдЬрдм рддрдХ рдХрд┐ AsyncValue рдореЗрдВ рдХреЛрдИ рдорд╛рди рдпрд╛ рддреНрд░реБрдЯрд┐ рджрд┐рдЦрд╛рдИ рди рджреЗред рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ, рд╣рдореЗрдВ std :: future :: get рдХрд╛ рдПрдирд╛рд▓реЙрдЧ рдЪрд╛рд╣рд┐рдПред рдпрд╣рд╛рдБ рдлрд╝рдВрдХреНрд╢рди рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╣реИ:

 template <typename ValuePred, typename ErrorPred> void wait(ValuePred valuePred, ErrorPred errorPred); 

рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рд╢рд░реНрдд рдЪрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ - рдПрдХ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдСрдмреНрдЬреЗрдХреНрдЯ рдЬрд┐рд╕реЗ рдПрдХ рдереНрд░реЗрдб рдореЗрдВ рдЙрдореНрдореАрдж рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ рдФрд░ рджреВрд╕рд░реЗ рдореЗрдВ рд╕рдХреНрд░рд┐рдп рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдкреНрд░рддреАрдХреНрд╖рд╛ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рд╣рдореЗрдВ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП, рдФрд░ рдЬрдм рдЕрд╕рдВрд╕рд╡реЗрд▓реНрдпреВ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдкреНрд░рдЧрддрд┐ рд╕реЗ рдореВрд▓реНрдп рдпрд╛ рддреНрд░реБрдЯрд┐ рдореЗрдВ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рдП, рддреЛ рд╣рдореЗрдВ рдкреНрд░рддреАрдХреНрд╖рд╛рдХрд░реНрддрд╛рдУрдВ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдПрдХ рдЕрдиреНрдп рдлрд╝реАрд▓реНрдб рдХреЛ AsyncValue рд╡рд░реНрдЧ рдореЗрдВ рдЬреЛрдбрд╝рдирд╛, рдЬреЛ рдХрд┐ рджреБрд░реНрд▓рдн рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдЬрдм рдкреНрд░рддреАрдХреНрд╖рд╛ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдореБрдЭреЗ рд╕реЛрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЗрд░рд┐рдд рдХрд┐рдпрд╛ рд╣реИ - рдХреНрдпрд╛ рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдХреЛ рд╡реИрдХрд▓реНрдкрд┐рдХ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ? рдЙрддреНрддрд░ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдпрд╣ рд╕рдВрднрд╡ рд╣реИ рдпрджрд┐ рдЖрдк std :: unique_ptr рд╕реНрдЯреЛрд░ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рддреЛ рдЗрд╕реЗ рдмрдирд╛рддреЗ рд╣реИрдВред рджреВрд╕рд░рд╛ рд╕рд╡рд╛рд▓ рд╕рд╛рдордиреЗ рдЖрдпрд╛ - рдХреНрдпрд╛ рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдХреЛ рд╡реИрдХрд▓реНрдкрд┐рдХ рдмрдирд╛рдирд╛ рд╕рдВрднрд╡ рд╣реИ рдФрд░ рди рдХрд┐ рдЧрддрд┐рд╢реАрд▓ рдЖрд╡рдВрдЯрди рдХрд░рдирд╛ред рдХреМрди рдкрд░рд╡рд╛рд╣ рдХрд░рддрд╛ рд╣реИ, рдХреГрдкрдпрд╛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рджреЗрдЦреЗрдВред рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ: рдкрд╣рд▓рд╛ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХреЙрд▓ рд╕реНрдЯреИрдХ рдкрд░ рдПрдХ QWaitCondition рд╕рдВрд░рдЪрдирд╛ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЕрдкрдиреЗ рдкреЙрдЗрдВрдЯрд░ рдХреЛ AsyncValue рдкрд░ рд▓рд┐рдЦрддрд╛ рд╣реИ, рдмрд╛рдж рдореЗрдВ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХреЙрд▓ рдХреА рдЬрд╛рдБрдЪ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдкреЙрдЗрдВрдЯрд░ рдЦрд╛рд▓реА рдирд╣реАрдВ рд╣реИ, рдЗрд╕ рдкреЙрдЗрдВрдЯрд░ рджреНрд╡рд╛рд░рд╛ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдпрджрд┐ рдкреЙрдЗрдВрдЯрд░ рдЦрд╛рд▓реА рд╣реИ, рддреЛ рдкрд╣рд▓реЗ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдКрдкрд░ рджреЗрдЦреЗрдВред ред

 class AsyncValueBase : public QObject { ... struct Waiter { //     QWaitCondition waitValue; //   wait quint16 subWaiters = 0; //  wait     QWaitCondition waitSubWaiters; }; //    Waiter* m_waiter = nullptr; }; template <typename ValuePred, typename ErrorPred> void wait(ValuePred valuePred, ErrorPred errorPred) { //   -      if (access(valuePred, errorPred)) return; //  AsyncValue   QMutexLocker writeLocker(&m_writeLock); //     if (access(valuePred, errorPred)) return; //    wait  if (!m_waiter) { //  Waiter   Waiter theWaiter; //       if SCOPE_EXIT { //     wait, //    theWaiter if (m_waiter->subWaiters > 0) { //    subWaiters   do { m_waiter->waitSubWaiters.wait(&m_writeLock); } while (m_waiter->subWaiters != 0); } //   wait  , //       Waiter m_waiter = nullptr; }; //    Waiter  AsyncValue //    wait   m_waiter = &theWaiter; //   AsyncValue     Value  Error //    do { m_waiter->waitValue.wait(&m_writeLock); } while (!access(valuePred, errorPred)); } //   wait   else { //       else SCOPE_EXIT { //      m_waiter->subWaiters -= 1; //     ->   wait if (m_waiter->subWaiters == 0) m_waiter->waitSubWaiters.wakeAll(); }; //      m_waiter->subWaiters += 1; //   AsyncValue     Value  Error //    do { m_waiter->waitValue.wait(&m_writeLock); } while (!access(valuePred, errorPred)); } } 

рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рд╣реА рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, AsyncValue рдореЗрдВ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реИ рддрд╛рдХрд┐ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рди рд╣реЛред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдирд┐: рд╢реБрд▓реНрдХ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдПрдХ рддрд░рд╣ рд╕реЗ рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдореЗрдВ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдереНрд░реЗрдб рдкреВрд▓ рдкрд░ AsyncValue рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ:

 template <typename AsyncValueType, typename Func, typename... ProgressArgs> bool asyncValueRunThreadPool(QThreadPool *pool, AsyncValueType& value, Func&& func, ProgressArgs&& ...progressArgs) { //    auto progress = std::make_unique<typename AsyncValueType::ProgressType>(std::forward<ProgressArgs>(progressArgs)...); //    auto progressPtr = progress.get(); //    AsyncValue if (!value.startProgress(std::move(progress))) return false; QtConcurrent::run(pool, [&value, progressPtr, func = std::forward<Func>(func)](){ SCOPE_EXIT { //     AsyncValue,    value.completeProgress(progressPtr); }; //  AsyncValue func(*progressPtr, value); }); return true; } 

рдкреБрд╕реНрддрдХрд╛рд▓рдп рджреЛ рдФрд░ рд╕рдорд╛рди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ: рдиреЗрдЯрд╡рд░реНрдХ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП asyncValueRunNetwork рдФрд░ asyncValueRunThread, рдЬреЛ рдПрдХ рдирдП рдмрдирд╛рдП рдЧрдП рдереНрд░реЗрдб рдкрд░ рдПрдХ рдСрдкрд░реЗрд╢рди рдХрд░рддрд╛ рд╣реИред рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрди рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕рд╛рдзрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╡реЗ рдЕрдиреНрдп рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред

рд╕реБрд░рдХреНрд╖рд╛ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП, AsyncValue рд╡рд░реНрдЧ рдХреЛ рдЕрдиреНрдп AsyncTrackErrorsPolicy рдЯреЗрдореНрдкрд▓реЗрдЯ рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ рдЖрдкрдХреЛ AsyncValue рдХреЗ рджреБрд░реБрдкрдпреЛрдЧ рдХрд╛ рдЬрд╡рд╛рдм рджреЗрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣рд╛рдВ AsyncTrackErrorsPolicy :: inProgressWhileDestruct рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ, рдЬрд┐рд╕реЗ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдСрдкрд░реЗрд╢рди рдЪрд▓рдиреЗ рдХреЗ рджреМрд░рд╛рди AsyncValue рдирд╖реНрдЯ рд╣реЛрдиреЗ рдкрд░ рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛:

  void inProgressWhileDestruct() const { Q_ASSERT(false && "Destructing value while it's in progress"); } 

рд╡рд┐рдЧреЗрдЯреНрд╕ рдХреЗ рд▓рд┐рдП, рдЙрдирдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛рдлреА рд╕рд░рд▓ рдФрд░ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╣реИред AsyncWidget рдПрдХ рдХрдВрдЯреЗрдирд░ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рддреНрд░реБрдЯрд┐, рдпрд╛ рдкреНрд░рдЧрддрд┐ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдЬреЗрдЯ рд╣реЛрддрд╛ рд╣реИ, рдпрд╛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ AsyncValue рдХрд┐рд╕ рд╕реНрдерд┐рддрд┐ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рдореВрд▓реНрдп рд╣реИред

  virtual QWidget* createValueWidgetImpl(ValueType& value, QWidget* parent); virtual QWidget* createErrorWidgetImpl(ErrorType& error, QWidget* parent); virtual QWidget* createProgressWidgetImpl(ProgressType& progress, QWidget* parent); 

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗрд╡рд▓ рдкрд╣рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рд╣реИ, рдореВрд▓реНрдп рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрдиреНрдп рджреЛ рдореЗрдВ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИрдВред

Qt-async рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЙрдореНрдкреИрдХреНрдЯ рд╣реЛ рдЧрдИ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдХрд╛рдлреА рдЙрдкрдпреЛрдЧреА рд╣реИред AsyncValue / AsyncWidget рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛, рдЬрд╣рд╛рдВ рдкрд╣рд▓реЗ рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдФрд░ рдПрдХ рд╕реНрдерд┐рд░ GUI рдереЗ, рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдЖрдзреБрдирд┐рдХ рдФрд░ рдЕрдзрд┐рдХ рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рдмрдирдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред

рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рдмреЛрдирд╕ рдХреЛ рдЕрдВрдд рддрдХ рдкрдврд╝рд╛ рд╣реИ - рдбреЗрдореЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рдПрдХ рд╡реАрдбрд┐рдпреЛ

Source: https://habr.com/ru/post/hi451722/


All Articles