.NET Processes | Threads | Application Domains | Contexts & Their Relationships Exposed

I have been asked many times about the relationships between Processes, Application Domains (AppDomains) and Threads. Lets explore today various aspects of these objects along with their functionalities  in context to .NET framework.

Quality means doing it right when no one is looking.
Henry Ford

Quality providers are actually background workers and are invisible, always!  
Some Worker

Before going into the details, let me go through the Process in computing itself. A Process is actually an instance of an application that is loaded + executed in the memory by the OS (Operating System) on demand. Or in other terms when you run an application, the OS creates/loads it into a separate and isolated memory that is composed of at least three regions, Code Segment, Data Segments and Stack Segment and OS ensures of no overlapping among them, as well as also are protected from other processes (complete isolation). The code instructions are loaded in the code segment while all the global variables, objects, etc. are loaded in the data segment. This segment has also a space for heap, that used to be managed by the user in older days (C, C++ or un-managed applications) where as in recent OS’s like .NET it is managed by the garbage collector (GC) that is actually part of the .NET framework (more on it later) . Stack is used for local variables created in a function as well as return address of execution of the method/function. Code Segment is a read only/protected memory while Data Segment & Stack are read-write memory regions. In context to .NET, System.Diagnostics.Process abstracts away the Process details and provides handy utilities to get information about the Processes in the .NET driven applications. 

Now the obvious question is what is a Thread. Well I can only say “good question”, lets move on. Ok, Ok, If you really insist   A thread is merely a reusable path of execution per unit time slice of a processor or if its a multiprocessor that has exactly same processors as threads, then the execution is per processor. In a multithreading applications you could have more than one separate execution paths where some are managed by the application itself and some are spawned by the application developers as needed. When you run the application, the process creates a main/primary thread of execution that is actually an entry point for an application, like in WPF it is the Application.Run(.) or in console applications is the Main(.) method. As needed further threads are spawned by this primary thread also known as worker threads. That is why if you look at the framework, System.Threading.Thread is responsible for creating threads not the System.Diagnostics.Process.  All threads of a process share its virtual address space or they share a common heap memory (like the static and global variables are shared) . They are also provided with “Thread Local Storage (TLS)” [Wicki] and private call stack. Read more about these concepts here [msdn].

You may ask, why we use multithreading model instead of single threaded one? Well, because, the real world applications are distributed / multithreaded.   No one person can do each and every thing in this world/universe all alone. There is a team work involved for a big achievement. The work load has to be divided among specialized people / threads to get the ultimate job done. Like wise computer programs are no different. If you give a responsibility of every thing to the Primary thread then you’ll see that application will be sluggish, some times non-responsive that you might need to move on to a coffee thread . So for responsiveness, for quality work like long mathematical calculations / specialized real world needs you go for multithreaded / multiprocessor based applications.

Here is a minimal example of how we spawn a worker thread, i hope you don't like it . For more intuitive example, please take a look at my earlier post on blocking queues, here is the link for it. [Blocking Queues]

Code Snippet
  1. public class Test1
  2.     {
  3.         public static void RunCounter()
  4.         {
  5.             System.Diagnostics.Debug.WriteLine("Entering Main thread | " +
  6.                 Thread.CurrentThread.GetHashCode().ToString());
  7.  
  8.             // Create a worker thread
  9.             Thread workerThread = new Thread(delegate()
  10.             {
  11.                 System.Diagnostics.Debug.WriteLine("Entering workerThread, Hash is| " + Thread.CurrentThread.GetHashCode().ToString());
  12.  
  13.                 for (int i = 0; i < 11; i++)
  14.                 {
  15.                     System.Diagnostics.Debug.WriteLine(string.Format("Worker Thread counter: {0}", i));
  16.                     Thread.Sleep(500);
  17.                 }
  18.             });
  19.             workerThread.Start();
  20.  
  21.             // we are still in the main/primary thread
  22.             System.Diagnostics.Debug.WriteLine("Entering Again Main thread, Hash is | " +
  23.                 Thread.CurrentThread.GetHashCode().ToString());
  24.  
  25.             for (int i = 0; i < 7; i++)
  26.             {
  27.                 System.Diagnostics.Debug.WriteLine(string.Format("Main thread counter : {0}", i));
  28.                 
  29.                 Thread.Sleep(1000);
  30.             }
  31.  
  32.             System.Diagnostics.Debug.WriteLine("--- Main thread, work done ---");
  33.         }
  34.  
  35.         /* Output :>
  36.             Entering Main thread | 10
  37.             Entering Again Main thread, Hash is | 10
  38.             Entering workerThread, Hash is| 3
  39.             Worker Thread counter: 0
  40.             Main thread counter : 0
  41.             Worker Thread counter: 1
  42.             Worker Thread counter: 2
  43.             Main thread counter : 1
  44.             Worker Thread counter: 3
  45.             Worker Thread counter: 4
  46.             Main thread counter : 2
  47.             Worker Thread counter: 5
  48.             Worker Thread counter: 6
  49.             Main thread counter : 3
  50.             Worker Thread counter: 7
  51.             Worker Thread counter: 8
  52.             Main thread counter : 4
  53.             Worker Thread counter: 9
  54.             Worker Thread counter: 10
  55.             Main thread counter : 5
  56.             The thread '<No Name>' (0x2bfc) has exited with code 0 (0x0).
  57.             Main thread counter : 6
  58.             --- Main thread, work done ---
  59.          * */
  60.     }

 

Now lets move on to .NET Application Domains or simply AppDomains. AppDomains are actually a subdivision or logical partition within Process in order to host .NET executables/assemblies. A process can have or can host one or more AppDomains as shown in the figure below (Figure-1). And an AppDomain can have one (+1) or more (+*) Contexts or Context Boundaries (I’ll come to this a little later).

Process Figure-1

ClassDiagram02 Figure-2

So now the question is why we need AppDomains. As you know when you run a .NET application it is managed by a OS/platform independent runtime known as Common Language Runtime (CLR). and the CLR gets this independency with the help of AppDomains and the class that is responsible for this job is System.AppDomain (Figure-2 above). AppDomains are like a light-weight process in terms of memory and processing requirements and they can be unloaded or loaded on-demand by the process or by the developer as needed.  Like the primary thread was created by the Process, the CLR automatically creates a default or primary AppDomain and hosts your application right away. Further AppDomains can be created by calling AppDomain.CreateDomain(.) static factory method. If you have more than one AppDomain, these AppDomains are isolated from each other and when they need to send information among each other, the information (like heap data) needs to be marshaled and that’s why it is derived from MarshalByRefObject or in simple terms the AppDomains are remotable objects (Look for C# Remoting for MarshalByRefObject).  The interesting methods in the AppDomain class are encircled above (Figure-2).

ClassDiagram03 Figure-3

Last but not least the “Contexts”; As mentioned earlier A process is composed/subdivided into 1-n AppDomains likewise AppDomains are composed of one to many Contexts or Context Boundaries. The context provides a special purpose boundary around an object, if adorned with a ContextAttribute. Like, if you look at the Figure-3, SynchronizationAttribute, if adorned on an object, the whole object will become thread-safe.  Also, like default AppDomain, the AppDomain creates a default context known as “context-0”. It is the first context where the objects resides who don't have special needs and these regular objects, loaded in some application domain, are also known as Context-Agile objects. Here is an example of a special need object, that needs synchronization or inherent thread-safety provided by CLR running for WPF applications.

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. using System.Runtime.Remoting.Contexts;
  7. using System.Threading;
  8.  
  9. namespace WpfTestApp
  10. {
  11.     // SynchronizationAttribute Enforces a synchronization domain for the
  12.     // current context and all contexts that share the same instance.
  13.     // Any object loaded in this context is thread-safe.
  14.     //
  15.     [Synchronization]
  16.     class SyncContextBoundObject : ContextBoundObject
  17.     {
  18.         public SyncContextBoundObject() {}
  19.  
  20.         public void ShowContextInfo()
  21.         {
  22.             // Display Current AppDomain Info
  23.             System.Diagnostics.Debug.WriteLine("AppDomain Id | " + AppDomain.CurrentDomain.Id.ToString());
  24.             System.Diagnostics.Debug.WriteLine("AppDomain FriendlyName | " + AppDomain.CurrentDomain.FriendlyName);
  25.             
  26.             // Display Current Thread Info
  27.             System.Diagnostics.Debug.WriteLine("Thread FriendlyName | " + Thread.CurrentThread.Name);
  28.             System.Diagnostics.Debug.WriteLine("Thread HashCode | " + Thread.CurrentThread.GetHashCode().ToString());
  29.  
  30.             // Display Current Context Info
  31.             System.Diagnostics.Debug.WriteLine("Context ID | " + Thread.CurrentContext.ContextID);
  32.             System.Diagnostics.Debug.WriteLine("Thread HashCode | " + Thread.CurrentContext.GetHashCode().ToString());
  33.  
  34.             // Display Context Properties...
  35.             foreach (IContextProperty contextProperty in Thread.CurrentContext.ContextProperties)
  36.             {
  37.                 System.Diagnostics.Debug.WriteLine("Context Property[.] | " + contextProperty.Name);
  38.             }
  39.             
  40.         }
  41.  
  42.         public void ShowPrimesUsingLinq(int n)
  43.         {
  44.             Func<int, IEnumerable<int>> primeNumbersExpr = (x) =>
  45.                  from i in Enumerable.Range(2, x - 1)
  46.                     where Enumerable.Range(2, i - 2).All(j => i % j != 0)
  47.                         select i;
  48.  
  49.             var resultSet = primeNumbersExpr(n);
  50.  
  51.             foreach (int i in resultSet)
  52.             {
  53.                 System.Diagnostics.Debug.WriteLine(i);
  54.             }
  55.         }
  56.     }
  57.  
  58.     public class Test2
  59.     {
  60.         public static void RunSyncContext()
  61.         {
  62.             SyncContextBoundObject syncObject = new SyncContextBoundObject();
  63.             syncObject.ShowContextInfo();
  64.             /* Output :>            
  65.                     AppDomain Id | 1
  66.                     AppDomain FriendlyName | WpfTestApp.vshost.exe
  67.                     Thread FriendlyName |
  68.                     Thread HashCode | 10
  69.                     Context ID | 1
  70.                     Context Property[.] | LeaseLifeTimeServiceProperty
  71.                     Context Property[.] | Synchronization
  72.             */
  73.             syncObject.ShowPrimesUsingLinq(11);
  74.         }
  75.     }
  76. }

One more thing that is important and quite notable is that although, their is no direct coherence between AppDomains and Threads (Figure-1) but a particular thread when activated is attached to One particular AppDomain. Or in other words, like AppDomains, the threads are not restricted to one domain, rather they are free to move around in different AppDomains, the only restriction is, a thread cannot be present in two different locations/domains at one time.

That's all for now folks, will talk to you more on threading next time. I’ll be looking forward to your feedbacks/comments, enjoy

 

If you enjoyed reading this blog, leave your valuable feedback and consider subscribing to the RSS feed. You can also subscribe to it by email. Also, you can follow me on Twitter. Thank you!

 

Comments (29) -

increase net income
2/23/2016 7:35:15 AM #

Keep on working, great job!  Feel free to visit my blog  increase net income - fullerqmxnniliik.webgarden.com/.../learn-the-smart-technique-to

We stumbled over here by a different web address and thought I might check things out. I like what I see so i am just following you. Look forward to looking over your web page repeatedly.

recycling resource
2/29/2016 10:57:50 AM #

It's a shame you don't have a donate button! I'd definitely donate to this excellent blog! I guess for now i'll settle for bookmarking and adding your RSS feed to my Google account. I look forward to brand new updates and will share this blog with my Facebook group. Talk soon!

Jared
2/29/2016 2:28:11 PM #

Some sort of treadmill is excellent intended for walking, running, plus also jogging.  My blog ...  Jared - www.blackplanet.com/.../view_posting.html

self inspiration
3/2/2016 8:21:37 PM #

Hi would you mind letting me know which webhost you're using? I've loaded your blog in 3 completely different browsers and I must say this blog loads a lot faster then most. Can you recommend a good internet hosting provider at a reasonable price? Many thanks, I appreciate it!

porno
3/5/2016 1:52:47 AM #

Hi to all, how is the whole thing, I think every one is getting more from this site, and your views are nice designed for new people.

program software downloads
3/11/2016 8:14:09 PM #

This is actually the best number of sites where their favorite application can be found by net geeks for free download.  program software downloads - http://dzhoppa111.com  that is free download, the biggest application directory for freeware and shareware download below.

porno
3/12/2016 8:21:33 AM #

I am sure this post has touched all the internet visitors, its really really nice paragraph on building up new web site.

vuelos baratos a buzios
3/13/2016 3:11:48 AM #

Hi there to every one, it's actually a fastidious for me to pay a visit this web site, it consists of useful Information.

https://Www.kompany.co.uk
3/14/2016 12:59:34 PM #

Unfortunately, it turns out that Coach O'Leary wasn't as decorated and degreed as he had claimed. Doing a rental background check serves as your primary protection against your property destruction, non-paying tenants, and abusive and criminal tenants. An online registration facility gives you the option of securing the registration with a payment.

Contractor umbrella companies uk
3/25/2016 12:50:31 AM #

Hello friends, how is everything, and what you would like to say on the topic of this piece of writing, in my view its in fact remarkable for me.  My web-site:  Contractor umbrella companies uk - www.4a-friend.com/.../index.php

www.porntsar.com
3/31/2016 9:51:47 PM #

Wonderful blog! I found it while browsing on Yahoo News. Do you have any suggestions on how to get listed in Yahoo News? I've been trying for a while but I never seem to get there! Many thanks

venus Factor Workout Free download
4/8/2016 10:21:01 PM #

This assists spend for our net hosting, and so on.  Here is my weblog:  venus Factor Workout Free download - http://s3.amazonaws.com/loswgt/index/133.html

Umbrella Company
4/11/2016 5:54:41 PM #

magnificent points altogether, you just gained a new reader. What could you suggest in regards to your put up that you just made some days in the past? Any sure?  Look at my web blog ::  Umbrella Company - http://durl.me/bxreci

umbrella companies for contractors
4/12/2016 7:06:40 AM #

Wow, amazing blog structure! How lengthy have you ever been blogging for? you make running a blog glance easy. The overall glance of your web site is wonderful, let alone the content material!  Feel free to visit my weblog -  umbrella companies for contractors - Www.Libertypropertytrust.com/.../...ltrademark.php

geekscafe.net
4/27/2016 5:52:59 AM #

Hi to every single one, it's really a fastidious for me to pay a quick visit this web site, it contains precious Information.

fiverr google login
5/5/2016 6:03:16 AM #

Many of their ‘gigs' - that's what Fiverr choices are called - are kinda sleazy.  my page ::  fiverr google login - www.rebelmouse.com/.../...he-cheap-1775194903.html

Lån 10000
5/26/2016 5:14:00 PM #

• renteudsving risiko.

bulk IT disposal london
5/30/2016 9:33:07 AM #

I recently couldn't leave without saying thank you in the base of my heart after scanning this website that is brilliant!

receive followers almost
6/6/2016 3:07:11 PM #

Whats up this is kind of of off topic but I was wanting to know if blogs use WYSIWYG editors or if you have to manually code with HTML. I'm starting a blog soon but have no coding know-how so I wanted to get guidance from someone with experience. Any help would be greatly appreciated!  My web site ::  receive followers almost - urmex.cl/

fiverr promo code feb 2016
6/7/2016 6:03:58 AM #

I am nonetheless searching for a method to use fiverr gigs as paypal just isn't obtainable in my nation.There is an option for bitcoin however i don't know about that either.  my homepage  fiverr promo code feb 2016 - freearticlesubmission.xyz/profile.php?a=84190

Lavon
6/23/2016 9:44:28 AM #

However, on older units, the codes need to be changed manually. A professional can help fix the damaged area or replace them all together. You can check the basic stuff- things you are familiar with- such as tracks and springs, rollers, checking if they work well together or if they're in good shape.

Wolley Movers
6/26/2016 3:16:44 PM #

Make sure to decide what pieces of furniture will be placed inside as well as rugs and accessories. Hence, these are some important tips in packing and preparing for moving. Help the workers in the loading and unloading process: In most of the cities in the US, like Bridgeview and Chicago, it is seen that movers follow a tight schedule.

Yacht in Dubai
6/30/2016 2:13:51 PM #

Post writing is also a fun, if you be acquainted with then you can write if not it is complex to write.

IT Recycling maidenhead
6/30/2016 10:20:19 PM #

Hi there! Do you use Twitter? I'd like to follow you if that would be okay. I'm undoubtedly enjoying your blog and look forward to new posts.

Rebelmouse.com
7/8/2016 10:46:04 PM #

We are a group of volunteers and opening a new scheme in our community. Your web site provided us with valuable info to work on. You have done a formidable job and our entire community will be grateful to you.

fiverr promo code february 2016
7/10/2016 4:38:03 AM #

If the content material is going to go up in your foremost site, Fiverr is not the very best place to source it. For $5, you are not going to get content that may blow readers away.  Look at my blog post:  fiverr promo code february 2016 - http://agme-news.com/profile.php?a=4982

best gun safes
7/17/2016 8:06:31 PM #

I like what you guys are up too. This sort of clever work and reporting! Keep up the terrific works guys I've included you guys to my blogroll.

biometrics gun safe
7/20/2016 12:49:09 AM #

I love your blog.. very nice colors & theme. Did you create this website yourself or did you hire someone to do it for you? Plz respond as I'm looking to create my own blog and would like to find out where u got this from. cheers

sentry fireproof
7/22/2016 1:02:11 AM #

I think you have observed some very interesting details, thanks for the post.

Silke
7/22/2016 7:32:29 PM #

I was able to find good info from your articles.

best gun safes
7/24/2016 9:44:05 PM #

I'm not sure exactly why but this weblog is loading extremely slow for me. Is anyone else having this issue or is it a problem on my end? I'll check back later and see if the problem still exists.

Webseriesnetwork.com
7/25/2016 12:05:37 AM #

I really appreciate this post. I have been looking everywhere for this! Thank goodness I found it on Bing. You have made my day! Thank you again!

Noreen
7/26/2016 10:03:41 PM #

Real fantastic information can be found on website.

Budmuzhikom.com
7/26/2016 10:58:41 PM #

We're a group of volunteers and opening a new scheme in our community. Your site provided us with valuable info to work on. You have done an impressive job and our entire community will be thankful to you.

I love what you guys are usually up too. This type of clever work and coverage! Keep up the terrific works guys I've included you guys to my own blogroll.

Kaley
7/30/2016 1:05:24 AM #

I'm not sure exactly why but this site is loading extremely slow for me. Is anyone else having this problem or is it a issue on my end? I'll check back later on and see if the problem still exists.

uhsystems.co.kr
7/30/2016 1:10:28 AM #

Hello There. I found your blog using msn. This is a very well written article. I will make sure to bookmark it and return to read more of your useful info. Thanks for the post. I will definitely comeback.

Hello There. I found your blog using msn. This is a very well written article. I'll make sure to bookmark it and come back to read more of your useful info. Thanks for the post. I will certainly comeback.

Darlene A. Brown
8/26/2016 8:26:41 AM #

I suddenly found this page in time of net surfing. I came to know visiting this page about something important thing. Thanks to all. You have done a great job.

losing Weight after 50
8/31/2016 12:00:15 PM #

Exceptional post but I was wanting to know if you could write a litte more on this subject? I'd be very grateful if you could elaborate a little bit more. Bless you!

rolex replica
9/17/2016 7:34:53 AM #

Of course, one way to shut them up is to buy yourself one of the a lot of acclaimed http://www.replicahause.me.uk in the world. Which is absolutely what you can do on July 18, if the French bargain abode Artcurial affairs to http://www.bestukwatches.co.uk advertise the pre-Daytona alarm George Lazenby wore in the 1969 James Bond blur On Her Majesty's Secret Service as allotment of its Fine http://www.toprolexsreplicauk.co.uk sale. (If you haven't apparent the movie, the watch's additional duke plays a key role in a train-based escape scene.)

Madison
10/12/2016 8:02:32 AM #

Gorgeous! That you don't come by information similar to this quickly and I am not so ungrateful! Maintain it-up men!

Boats for sale dubai
10/20/2016 10:21:14 AM #

Amazing article about .net . Clear and Sharp.. Keep it up

the accountant movie 2016
10/22/2016 11:48:42 AM #

Sweet blog! I found it while surfing around on Yahoo News. Do you have any tips on how to get listed in Yahoo News? I've been trying for a while but I never seem to get there! Appreciate it

Sewer
11/1/2016 3:02:24 AM #

I have read some excellent stuff here. Definitely price bookmarking for revisiting. I surprise how much attempt you place to create the sort of excellent informative website.  my homepage:  Sewer - www.arizonawebdesign.org/index.php

damselindefense.strikingly.com
11/3/2016 8:18:43 AM #

I read this article fully concerning the resemblance of most up-to-date and preceding technologies, it's remarkable article.

http://onecoinreviews.webs.com/
11/3/2016 8:29:53 AM #

I visited several blogs but the audio quality for audio songs present at this web page is genuinely wonderful.

Damsel In Defense
11/3/2016 8:35:50 AM #

You are so awesome! I do not suppose I've truly read anything like this before. So good to discover somebody with a few unique thoughts on this subject. Seriously.. thank you for starting this up. This site is one thing that's needed on the web, someone with a bit of originality!

yesonecoinreview.tumblr.com
11/3/2016 8:45:19 AM #

Good site you have here.. It's difficult to find excellent writing like yours these days. I seriously appreciate individuals like you! Take care!!

onecoinreview.soup.io
11/3/2016 8:47:28 AM #

I'm not sure why but this website is loading extremely slow for me. Is anyone else having this problem or is it a issue on my end? I'll check back later on and see if the problem still exists.

damseldefense.wordpress.com
11/3/2016 9:59:26 AM #

Hi there are using Wordpress for your blog platform? I'm new to the blog world but I'm trying to get started and create my own. Do you need any html coding knowledge to make your own blog? Any help would be greatly appreciated!

kredyt bez bik i krd przez internet
11/4/2016 3:17:53 PM #

I loved as much as you will receive carried out right here. The sketch is attractive, your authored material stylish. nonetheless, you command get bought an edginess over that you wish be delivering the following. unwell unquestionably come further formerly again since exactly the same nearly a lot often inside case you shield this hike. bbs.longtuart.com/home.php?mod=space&uid=72566

Residential Fences
11/7/2016 5:34:23 AM #

I not to mention my buddies appeared to be looking at the great recommendations located on your web page then unexpectedly I got a terrible feeling I never thanked the web site owner for those techniques. All of the men had been as a consequence warmed to read through them and now have extremely been enjoying them. I appreciate you for actually being well thoughtful and for deciding upon varieties of superb areas most people are really desirous to learn about. My honest regret for not saying thanks to  sooner.  Also visit my website ::  Residential Fences - Feedback.Kat.Libris.Kb.se/profile.php?id=393013

aaronandshara.tumblr.com
11/8/2016 9:14:45 AM #

Thanks designed for sharing such a pleasant opinion, post is fastidious, thats why i have read it entirely

www.instapaper.com
11/11/2016 9:29:57 PM #

Very great post. I simply stumbled upon your weblog and wanted to mention that I've truly enjoyed surfing around your blog posts. In any case I'll be subscribing for your rss feed and I'm hoping you write once more very soon!

Larhonda
11/12/2016 2:17:47 AM #

Have you ever thought about adding a little bit more than just your articles? I mean, what you say is important and everything. But think of if you added some great images or video clips to give your posts more, "pop"! Your content is excellent but with pics and clips, this website could undeniably be one of the greatest in its niche. Terrific blog!

Hello! I know this is somewhat off topic but I was wondering if you knew where I could get a captcha plugin for my comment form? I'm using the same blog platform as yours and I'm having difficulty finding one? Thanks a lot!

twitter.com
11/15/2016 8:18:09 AM #

Hello exceptional blog! Does running a blog such as this require a massive amount work? I have no understanding of programming however I was hoping to start my own blog in the near future. Anyways, should you have any suggestions or tips for new blog owners please share. I know this is off topic nevertheless I just wanted to ask. Kudos!

I was curious if you ever considered changing the layout of your website? Its very well written; I love what youve got to say. But maybe you could a little more in the way of content so people could connect with it better. Youve got an awful lot of text for only having 1 or two pictures. Maybe you could space it out better?

Hotel Remodeling
11/19/2016 6:12:47 PM #

Thanks for sharing your thoughts on granite surface area. Regards  Take a look at my web page  Hotel Remodeling - http://wl500G.info/member.php?u=67521-PhyllisDud

Leer hoe penisvergroting
11/22/2016 5:16:21 PM #

Hello! I've been reading your weblog for some time now and finally got the courage to go ahead and give you a shout out from  Lubbock Texas! Just wanted to mention keep up the good job!

cryptonuke review
11/26/2016 2:06:59 AM #

I was curious if you ever thought of changing the structure of your website? Its very well written; I love what youve got to say. But maybe you could a little more in the way of content so people could connect with it better. Youve got an awful lot of text for only having one or 2 images. Maybe you could space it out better?

www.diigo.com
11/29/2016 3:28:00 PM #

always i used to read smaller content that  as well clear their motive, and that is also happening with this article which I am reading here.

Jack
12/2/2016 12:15:34 AM #

You have made some good points there. I checked on the web for additional information about the issue and found most individuals will go along with your views on this site.  Feel free to visit my homepage ::  Jack - http://yahoo.org

Add comment