构建一个工作类及封装启动它的函数如下:
工作者头文件 “EventWorker.h”
#pragma once
#include <string>
using namespace std;
#define WORKER_HANDLE int
enum class WORK_STATUS
{
FAILED = 0,
SUCCEED = 1,
WORKING = 2,
OTHER
};
struct WORDDONE_CALLBACK_PARAM
{
public:
void* pUserParam; //使用者对象指针
string szWorkerName; //工作者
string szWorkData; //工作完成返回的数据
WORDDONE_CALLBACK_PARAM()
{
pUserParam = NULL;
szWorkerName = "";
szWorkData = "";
}
};
typedef void(_stdcall* DoWorkCallBack) (WORDDONE_CALLBACK_PARAM* pUserParam);
WORK_STATUS InitWorker(string szWorkName, WORKER_HANDLE* phOutWorkerHandle);
WORK_STATUS ReleaseWorker(WORKER_HANDLE hWorkerHandle);
WORK_STATUS StartWork(WORKER_HANDLE hWorkerHandle, void* pUserParam, DoWorkCallBack callBackFun);
WORK_STATUS StopWork(WORKER_HANDLE hWorkerHandle);
工作者源文件 “EventWorker.cpp”
#include "EventWorker.h"
#include <Windows.h>
#include <sstream>
#include <map>
#include <iostream>
class Worker
{
private:
string m_szName;
string m_workData;
bool m_bStartWork;
bool m_bIsRunning;
WORDDONE_CALLBACK_PARAM m_callBackParam;
DoWorkCallBack m_callBackFun;
public:
Worker()
{
m_szName = "";
m_workData = "";
m_bStartWork = false;
m_bIsRunning = false;
m_callBackFun = NULL;
}
Worker(string szName)
{
m_szName = szName;
m_workData = "";
m_bStartWork = false;
m_bIsRunning = false;
m_callBackFun = NULL;
}
void SetName(string szName)
{
m_szName = szName;
}
string GetName()
{
return m_szName;
}
void SetCallBackParam(DoWorkCallBack callBackFun, void* pUserParam)
{
m_callBackParam.pUserParam = pUserParam;
m_callBackFun = callBackFun;
}
void StartWork()
{
m_bStartWork = true;
while (m_bStartWork)
{
m_bIsRunning = true;
stringstream ss;
ss << 100 * rand();
m_workData = ss.str();
m_callBackParam.szWorkerName = this->m_szName;
m_callBackParam.szWorkData = this->m_workData;
if (m_callBackFun)
{
m_callBackFun(&m_callBackParam); //回调事件
}
Sleep(6000);
}
m_bIsRunning = false;
}
void StopWork()
{
m_bStartWork = false;
while (m_bIsRunning)
{
Sleep(10);
}
}
};
map<int, Worker> m_workerArray;
WORK_STATUS InitWorker(string szWorkName, WORKER_HANDLE* phOutWorkerHandle)
{
int iWorkHandle = 0;
bool bExistWorker = false;
map<int, Worker>::iterator iter;
for (iter = m_workerArray.begin(); iter != m_workerArray.end(); iter++)
{
if (szWorkName == iter->second.GetName())
{
bExistWorker = true;
iWorkHandle = iter->first;
break;
}
}
if (!bExistWorker)
{
Worker newWorker(szWorkName);
while (m_workerArray.find(iWorkHandle) != m_workerArray.end())
{
iWorkHandle++; //独一无二的句柄
}
m_workerArray[iWorkHandle] = newWorker;
}
*phOutWorkerHandle = iWorkHandle;
return WORK_STATUS::SUCCEED;
}
WORK_STATUS ReleaseWorker(WORKER_HANDLE hWorkerHandle)
{
if (m_workerArray.find(hWorkerHandle) != m_workerArray.end())
{
m_workerArray[hWorkerHandle].StopWork();
m_workerArray.erase(hWorkerHandle);
}
return WORK_STATUS::SUCCEED;
}
DWORD WINAPI DoWorking_Task(void* arg)
{
Worker* pWorker = (Worker*)arg;
if (pWorker)
{
pWorker->StartWork();
}
return 0;
}
WORK_STATUS StartWork(WORKER_HANDLE hWorkerHandle, void* pUserParam, DoWorkCallBack callBackFun)
{
WORK_STATUS workStatus = WORK_STATUS::FAILED;
if (m_workerArray.find(hWorkerHandle) != m_workerArray.end())
{
m_workerArray[hWorkerHandle].SetCallBackParam(callBackFun, pUserParam);
HANDLE handle = ::CreateThread(NULL, 0, DoWorking_Task, (void*)&m_workerArray[hWorkerHandle], 0, NULL);
::CloseHandle(handle);
workStatus = WORK_STATUS::SUCCEED;
}
return workStatus;
}
WORK_STATUS StopWork(WORKER_HANDLE hWorkerHandle)
{
WORK_STATUS workStatus = WORK_STATUS::FAILED;
if (m_workerArray.find(hWorkerHandle) != m_workerArray.end())
{
m_workerArray[hWorkerHandle].StopWork();
workStatus = WORK_STATUS::SUCCEED;
}
return workStatus;
}
测试这个工作者类:
#include "EventWorker.h"
#include <cstring>
#include <iostream>
using namespace std;
//工作的回调函数
static void _stdcall CallBackWorkFun(WORDDONE_CALLBACK_PARAM* pUserParam)
{
cout << "worker: " << pUserParam->szWorkerName << " is working, work-data: " << pUserParam->szWorkData << endl;
}
int main()
{
cout << "Hello, please follow the instructions below to Do work!\n";
cout << "Enter 'NEW[worker-Name]' to build a new worker\n";
cout << "it will back a handle number like 0,1,2.. which use to start work by enter 'START[0]','START[1]'.. \n";
cout << "and stop work by enter 'STOP[0]','STOP[1]'..\n";
cout << "Enter'EXIT' to exit program, Just Go!\n";
GOTO_LABEL_START: //开始位置
string szText;
cin >> szText;
if (szText == "EXIT") return 0;
else if (szText.find("NEW")!= string::npos)
{
int iHandle;
int startIndex = szText.find("[") + 1;
int endIndex = szText.find("]");
if (startIndex != string::npos && endIndex != string::npos)
{
string szName = szText.substr(startIndex, endIndex - startIndex);
if (InitWorker(szName, &iHandle) == WORK_STATUS::SUCCEED)
{
cout << "worker: " << szText << " Success. " << "worker handle = " << iHandle << endl;
bool bStartWork = false;
while (true)
{
cin >> szText;
if (szText == "EXIT") break;
if (szText.find("START") != string::npos)
{
cout << "StartWork.\n";
startIndex = szText.find("[") +1;
endIndex = szText.find("]");
if (startIndex != string::npos && endIndex != string::npos)
{
string szHandle = szText.substr(startIndex, endIndex - startIndex);
int ilHandle = atoi(szHandle.c_str());
WORK_STATUS workStatus = StartWork(ilHandle, NULL, CallBackWorkFun); //如果在类中操作,可将类指针对象传入pUserParam
bStartWork = workStatus == WORK_STATUS::SUCCEED;
}
}
else if (bStartWork && szText.find("STOP") != string::npos)
{
startIndex = szText.find("[") +1;
endIndex = szText.find("]");
if (startIndex != string::npos && endIndex != string::npos)
{
string szHandle = szText.substr(startIndex, endIndex - startIndex);
int ilHandle = atoi(szHandle.c_str());
StopWork(ilHandle);
cout << "StopWork.\n";
}
}
else
{
cout << "commad is error, please retry.\n";
}
}
}
else
{
cout << "worker: " << szText << " Failed. " << endl;
goto GOTO_LABEL_START; //这里只是演示使用,实际项目不建议大家使用goto语句
}
}
}
return 0;
}
备注: 测试案例只是简单构建一个对象来演示使用这个工作者类,实际可以操作建立更多对象工作.