ANPOP Developers Center > Multiple Threading Application with Visual C++
You should download the anpop installer and install it on your machine at first. If you want to distribute or deploy anpop without anpop installer, please click here to learn more.
Why use multi-threading?
Multi-threading application is the ability to execute more that one tasks simultaneous in a single application which subsequently enhance the application performance.
Create thread in Visual C++
It is very easy to create thread in Visual C++ application. First you need to define a static function, this function would be the entry of worker thread. The following code demonstrates how to create a worker thread.
#include "stdafx.h"
#include <comdef.h>
#include "anpop.tlh"
using namespace ANPOPLib;
//this function will be called when the thread startup
static DWORD __stdcall RetrieveEmail( LPVOID lpArg )
{
::CoInitialize( NULL );
IPOPMAINPtr oPop3Ptr = NULL;
oPop3Ptr.CreateInstance("ANPOP.POPMAIN");
//retrieve email in worker thread
return 0;
}
int main( int argc, char* argv[] )
{
HANDLE hThread = INVALID_HANDLE_VALUE;
DWORD dwThreadId = 0;
hThread = ::CreateThread( NULL,
0,
(LPTHREAD_START_ROUTINE)RetrieveEmail,
(LPVOID)NULL,
0,
&dwThreadId );
// do something.
return 0;
}
Now, we can use ANPOP to retrieve email by RetrieveEmail method. As we create multi-threading in this application, we can access multiple pop3 accounts concurrently.
Thread model
Objects of ANPOP are based on Apartment Threading. So we suggest you create each object instance for each thread just like the sample code above. And do not use the object instance which is not created in current thread.
Thread communication and synchronization
How can we transfer data to a sub-thread and how can we assure that the data can only be accessed by one thread? The following code demonstrates how to use SimpleArry and CComAutoCriticalSection to share and lock data.
#include "stdafx.h"
#include <atlbase.h>
#include <comdef.h>
#include "anpop.tlh"
using namespace ANPOPLib;
typedef struct _tagPop3Account
{
CHAR szServer[256];
CHAR szUser[256];
CHAR szPassword[256];
}POP3ACCOUNT, *LPPOP3ACCOUNT;
CSimpleArray<LPPOP3ACCOUNT> g_arTask;
CComAutoCriticalSection g_cs;
//push an account into array
static PushTask( LPPOP3ACCOUNT pAccount )
{
g_cs.Lock();
g_arTask.Add( pAccount );
g_cs.Unlock();
}
//pop an account from array
static LPPOP3ACCOUNT PopTask()
{
LPPOP3ACCOUNT pAccount = NULL;
g_cs.Lock();
if( g_arTask.GetSize() > 0 )
{
pAccount = g_arTask[0];
g_arTask.RemoveAt(0);
}
g_cs.Unlock();
return pAccount;
}
//this function will be called when the thread startup
static DWORD __stdcall RetrieveEmail( LPVOID lpArg )
{
::CoInitialize( NULL );
IPOPMAINPtr oPop3Ptr = NULL;
oPop3Ptr.CreateInstance("ANPOP.POPMAIN");
LPPOP3ACCOUNT pAccount = NULL;
while( TRUE )
{
pAccount = PopTask(); //get an account from array
if( pAccount == NULL )
{
::Sleep( 100 );
continue;
}
oPop3Ptr->Connect( pAccount->szServer, pAccount->szUser, pAccount->szPassword );
//retrieve email in worker thread
delete pAccount;
pAccount = NULL;
}
return 0;
}
int main( int argc, char* argv[] )
{
HANDLE hThread = INVALID_HANDLE_VALUE;
DWORD dwThreadId = 0;
hThread = ::CreateThread( NULL,
0,
(LPTHREAD_START_ROUTINE)RetrieveEmail,
(LPVOID)NULL,
0, //create a worker thread.
&dwThreadId ); //you can also create multiple worker threads here
LPPOP3ACCOUNT pAccount = new POP3ACCOUNT;
strcpy( pAccount->szServer, "mail.adminsystem.net");
strcpy( pAccount->szUser, "test@adminsystem.net" );
strcpy( pAccount->szPassword, "test" );
PushTask( pAccount ); //push an account into array
//push other accounts into array
return 0;
}
Free Email Support
Not enough? Please contact our technical support team.
Support@EmailArchitect.NET
VIP@EmailArchitect.NET(Registered
User)
Remarks
We usually reply emails in 24hours. The reason for getting no response is
likely that your smtp server bounced our reply. In this case, please try to use
another email address to contact us. Your Hotmail or Yahoo email account is
recommended.
|