SOUI中TaskLoop組件介紹


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

GIT地址:

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

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

 

下面介紹一個最近增加的組件:TaskLoop.

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

和使用其它SOUI組件一樣,要使用異步任務模塊,先完成組件的編譯,然后就可以通過SComMgr來創建TaskLoop對象。

 

打開soui.08.sln可以看到上面工程組織結構。使用其它版本VS的朋友,可以用build.bat來生成自己需要的VS版本。

我們先看一看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對象中的任務順序在同一個線程中執行。

任務的優先級默認是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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM