---
title:  Running the Connection Pool Code
---

<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

Examples demonstrate a simple procedure to create a pool factory and then create a pool instance in C++ and C\#. They also help you to execute a query.

The examples create a pool with locators. Ensure that you create a pool with locators or endpoints, but not both. The first example demonstrates creating a pool by adding locators. The second example demonstrates creating a pool by adding servers. For more information, see the example in the QuickStart Guide.

## Connection Pool Creation and Execution Using C++

``` pre
PropertiesPtr prptr = Properties::create();
systemPtr = CacheFactory::createCacheFactory(prptr);

cachePtr = systemPtr->create();
PoolFactoryPtr poolFacPtr = PoolManager::createFactory();
//to create pool add either endpoints or add locators or servers
//pool with endpoint, adding to pool factory
//poolFacPtr->addServer("localhost", 12345 /*port number*/);
//pool with locator, adding to pool factory
poolFacPtr->addLocator("localhost", 34756 /*port number*/);
PoolPtr pptr = NULLPTR;
if ((PoolManager::find("examplePool")) == NULLPTR) {
  // Pool with this name does not exist
  pptr = poolFacPtr->create("examplePool");
}
RegionFactoryPtr regionFactory =
    cachePtr->createRegionFactory(CACHING_PROXY);
regionPtr = regionFactory
    ->setPoolName("examplePool")
    ->create("regionName");
QueryServicePtr qs = cachePtr->getQueryService("examplePool");
```

## Connection Pool Creation and Execution Using C\# .NET

``` pre
Properties prop = Properties.Create();
CacheFactory cacheFactory = CacheFactory.CreateCacheFactory(prop);
Cache cache = cacheFactory.Create();

PoolFactory poolFact = PoolManager.CreateFactory();
//to create pool add either endpoints or add locators
//pool with endpoint, adding to pool factory.
poolFact.AddServer("localhost", 40404 /*port number*/);
//pool with locator, adding to pool factory
//poolFact.AddLocator("hostname", 15000 /*port number*/);
Pool pool = null;
if (PoolManager.Find("poolName") == null) {
  pool = poolFact.Create("poolName");
}
int loadConditInterval = pool.LoadConditioningInterval;
RegionFactory regionFactory =
    cache.CreateRegionFactory(RegionShortcut.CACHING_PROXY);
IRegion<string, string> region =
    regionFactory.SetPoolName(poolName).Create<string, string>(regionName);
```


