///////////////////////////////////////////////////////////////////////// // SynchronizedContext.cpp - illustrate use of context-bound object // // // // Jim Fawcett, CSE681 - Software Modeling and Analysis, Fall 2006 // ///////////////////////////////////////////////////////////////////////// using namespace System; using namespace System::Collections; using namespace System::Collections::Generic; using namespace System::Runtime::Remoting::Contexts; using namespace System::Threading; ///////////////////////////////////////////////////////////////////////// // SQueue class defines synchronized class using context-bound attribute [SynchronizationAttribute(SynchronizationAttribute::REQUIRED)] public ref class SQueue : public ContextBoundObject { Queue^ _ptrQueue; public: SQueue() : _ptrQueue(gcnew Queue()) { Console::Write( "\n Queue constructor's ContextID = {0}\n", Thread::CurrentThread->CurrentContext->ContextID ); } void Enqueue(Object^ obj) { Console::Write( "\n Enqueuing ContextID = {0}\n", Thread::CurrentThread->CurrentContext->ContextID ); _ptrQueue->Enqueue(obj); } Object^ Dequeue() { Console::Write( "\n Dequeuing ContextID = {0}\n", Thread::CurrentThread->CurrentContext->ContextID ); return _ptrQueue->Dequeue(); } property int Count { int get() { return _ptrQueue->Count; } } }; ref class threadProc { SQueue^ _sQ; // ///////////////////////////////////////////////////////////////////////// // threadProc class provides run() for child thread public: threadProc(SQueue^ sQ) { _sQ = sQ; } void run() { Console::Write( "\n threadProc ContextID = {0}\n", Thread::CurrentThread->CurrentContext->ContextID ); while(true) { while(_sQ->Count == 0) Thread::CurrentThread->Sleep(100); String^ msg = static_cast(_sQ->Dequeue()); Console::Write("\n dequeued message = {0}",msg); if(msg == "quit") break; } } }; //----< test stub >------------------------------------------------------ void main() { Console::Write("\n Demonstrate application of context-bound object "); Console::Write("\n =================================================\n"); Console::Write( "\n Client ContextID = {0}\n", Thread::CurrentThread->CurrentContext->ContextID ); SQueue^ sQ = gcnew SQueue(); /////////////////////////////////////////////////////////////////////// // Can also create an instance just as you would in a child AppDomain // SQueue^ sQ = (SQueue^)Activator::CreateInstance(SQueue::typeid); threadProc^ tp = gcnew threadProc(sQ); Thread^ child = gcnew Thread(gcnew ThreadStart(tp,&threadProc::run)); child->Start(); String^ msg = "message"; sQ->Enqueue(msg + "#1"); sQ->Enqueue(msg + "#2"); sQ->Enqueue(msg + "#3"); sQ->Enqueue(msg + "#4"); sQ->Enqueue(msg + "#5"); sQ->Enqueue(msg + "#6"); sQ->Enqueue("quit"); child->Join(); Console::Write("\n\n"); }