private void Download(object obj)
 {
     try
     {
         DownloadThreadArgs       args = obj as DownloadThreadArgs;
         List <DownloadLevelTile> threadDownloadLevelTiles = args.DownloadLevelTiles;
         int retryCount = 0;
         for (int i = 0; i < threadDownloadLevelTiles.Count; ++i)
         {
             GPoint p    = threadDownloadLevelTiles[i].TilePoint;
             int    zoom = threadDownloadLevelTiles[i].TileZoom;
             try
             {
                 if (CacheTiles(zoom, p, provider))
                 {
                     retryCount = 0;
                     lock (locker)
                     {
                         ++downloadSize;
                         if (downloadSize == allTileSize)
                         {
                             IsComplete = true;
                         }
                     }
                 }
                 else
                 {
                     if (++retryCount <= retry)
                     {
                         --i;
                         continue;
                     }
                     else
                     {
                         retryCount = 0;
                         downloadFailedTiles.Enqueue(threadDownloadLevelTiles[i]);
                     }
                 }
             }
             catch (Exception exception)
             {
                 log.Error(exception);
             }
         }
         log.Info("One thread download complete.");
     }
     catch (Exception ex)
     {
         log.Error(ex);
     }
 }
        public void StartDownload(TileDownloaderArgs tileDownloaderArgs)
        {
            GMaps.Instance.UseMemoryCache  = false;
            GMaps.Instance.CacheOnIdleRead = false;

            isComplete   = false;
            downloadSize = 0;

            provider = tileDownloaderArgs.MapProvider;
            List <DownloadLevelTile> downloadTiles = tileDownloaderArgs.DownloadTiles;

            allTileSize = downloadTiles.Count;
            int singelNum = (int)(allTileSize / threadNum);
            int remainder = (int)(allTileSize % threadNum);

            if (PrefetchTileStart != null)
            {
                PrefetchTileStart(this, new TileDownloadEventArgs(0));
            }

            if (singelNum == 0)
            {
                threadNum = 1;
            }
            for (int i = 0; i < threadNum; i++)
            {
                int startIndex = i * singelNum;
                int endIndex   = startIndex + singelNum - 1;
                if (remainder != 0 && (threadNum - 1) == i)
                {
                    endIndex = allTileSize - 1;
                }
                DownloadThreadArgs args = new DownloadThreadArgs(downloadTiles.GetRange(startIndex, endIndex - startIndex + 1));
                thread[i] = new Thread(new ParameterizedThreadStart(Download));
                thread[i].Start(args);
            }

            updateUiTimer.Start();
            downloadFailedThread.Start();
        }