SOUI中TaskLoop組件介紹

SOUI是一套開源(MIT協議)的Windows平臺下的DirectUI框架,它提供了大量的高效控件,也提供了不少擴展組件,目前已經持續維護近10年,在大量的項目中證實穩定可靠。git

GIT地址:github

國內:https://gitee.com/setoutsoft/soui網絡

國外:https://github.com/soui2/soui框架

 

下面介紹一個最近增長的組件:TaskLoop.異步

TaskLoop是一個異步任務模塊。對於有網絡請求的狀況,異步任務是常規需求。函數

和使用其它SOUI組件同樣,要使用異步任務模塊,先完成組件的編譯,而後就能夠經過SComMgr來建立TaskLoop對象。oop

 

打開soui.08.sln能夠看到上面工程組織結構。使用其它版本VS的朋友,能夠用build.bat來生成本身須要的VS版本。post

咱們先看一看staskloop-i.h中的接口定義。動畫

 1 #pragma once
 2 #include <unknown/obj-ref-i.h>
 3 
 4 namespace SOUI
 5 {
 6     struct IRunnable
 7     {
 8         virtual ~IRunnable() {}
 9         virtual IRunnable* clone() const = 0;
10         virtual void run() = 0;
11         virtual void *getObject() = 0;
12         virtual const char *getClassInfo() const = 0;
13     };
14 
15     struct ITaskLoop : public IObjRef
16     {
17         enum Priority
18         {
19             High = 1,
20             Normal = 0,
21             Low = -1,
22         };
23 
24         virtual bool getName(char *pszBuf, int nBufLen) = 0;
25 
26         /**
27         * Start a thread to run.
28         * @param priority the thread priority
29         */
30         virtual void start(const char * pszName,Priority priority) = 0;
31 
32         /**
33         * Stop thread synchronized.
34         */
35         virtual void stop() = 0;
36 
37         /**
38         * postTask post or send a tasks to this task manager.
39         * @param runnable the to be run task object.
40         * @param waitUntilDone, true for send and false for post.
41         * @param priority, the task priority.
42         * @return the task id, can be used by cancelTask.
43         */
44         virtual long postTask(const IRunnable *runnable, bool waitUntilDone, int priority=0) = 0;
45 
46         /**
47         * Remove tasks for a specific object from task loop pending task list
48         * @param object the specific object wants pending functors to be removed
49         */
50         virtual void cancelTasksForObject(void *object) = 0;
51 
52         /**
53         * Cancel tasks for a specific task ID list
54         * @param taskList the task ID list to be canceled
55         * @return the removed task list.
56         */
57         virtual bool cancelTask(long taskId) = 0;
58 
59         /**
60         * get the total task number in the task loop queue.
61         * @return total task number in task loop queue
62         */
63         virtual int getTaskCount() const = 0;
64 
65         /**
66         * get the run loop status.
67         * @return the running status
68         */
69         virtual bool isRunning() = 0;
70 
71         /**
72         * get the running task info.
73         * @param buf, to receive task info buf.
74         * @param bufLen, buffer length
75         * @return false - no task is running; true - succeed.
76         */
77         virtual bool getRunningTaskInfo(char *buf, int bufLen) = 0;
78     };
79 }

 

  建立出ITaskLoop接口後,先調用start來啓動,再調用postTask來添加一個異步任務。添加到同一個TaskLoop對象中的任務順序在同一個線程中執行。ui

任務的優先級默認是0,若是不少任務在排除,新加入的任務但願優先執行,則將nPriority這個參數設置爲一個更大的值,任務插入隊列的時候,自動根據nPriority排序,nPriority越大,排序越前。

postTask須要提供一個IRunnable對象來運行。

使用SOUI/helper/sfunctor.hpp能夠方便的將一個對象的成員函數或者全局函數轉換成爲一個IRunnable對象。

下面看一下demo中如何使用ITaskLoop.

//演示異步任務。
class CAsyncTaskObj
{
public:
    void task1(int a)
    {
        SLOG_INFO("task1,a:" << a);
    }

    void task2(int a, const std::string & b)
    {
        SLOG_INFO("task2,a:" << a<<" b:"<<b.c_str());
    }
};

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR /*lpstrCmdLine*/, int /*nCmdShow*/)
{
    
    //必需要調用OleInitialize來初始化運行環境
    HRESULT hRes = OleInitialize(NULL);
    SASSERT(SUCCEEDED(hRes));


    //使用imgdecoder-png圖片解碼模塊演示apng動畫
    SComMgr2 *pComMgr = new SComMgr2(_T("imgdecoder-png"));
    


    {

  
        //演示異步任務。
        CAutoRefPtr<ITaskLoop>  pTaskLoop;
        if (pComMgr->CreateTaskLoop((IObjRef**)&pTaskLoop))
        {
            CAsyncTaskObj obj;
            pTaskLoop->start("test", ITaskLoop::Low);
            STaskHelper::post(pTaskLoop, &obj, &CAsyncTaskObj::task1, 100,true);
            STaskHelper::post(pTaskLoop, &obj, &CAsyncTaskObj::task2, 100,"abc", true);
            pTaskLoop->stop();
            pTaskLoop = NULL;
        }
      }
     //....
     return 0;
}

注:

demo爲了方便演示其實是在工做線程中使用了同步等待。

使用TaskLoop最好結合SOUI的NotifyCenter對象一塊兒使用,在異步任務中須要通知UI層,使用NotifyCenter是最簡單有效的。

更多用法參考SOUI的壁紙demo: https://github.com/soui-demo/SouiWallPaper

 

啓程軟件 2019-02-03

相關文章
相關標籤/搜索