Index: /trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java	(revision 14426)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java	(revision 14427)
@@ -1770,12 +1770,16 @@
     public class PrecacheTask implements TileLoaderListener {
         private final ProgressMonitor progressMonitor;
-        private int totalCount;
+        private final int totalCount;
         private final AtomicInteger processedCount = new AtomicInteger(0);
         private final TileLoader tileLoader;
+        private final Set<Tile> requestedTiles;
 
         /**
          * @param progressMonitor that will be notified about progess of the task
+         * @param bufferY
+         * @param bufferX
+         * @param points
          */
-        public PrecacheTask(ProgressMonitor progressMonitor) {
+        public PrecacheTask(ProgressMonitor progressMonitor, List<LatLon> points, double bufferX, double bufferY) {
             this.progressMonitor = progressMonitor;
             this.tileLoader = getTileLoaderFactory().makeTileLoader(this, getHeaders(tileSource), minimumTileExpire);
@@ -1784,4 +1788,27 @@
                         TMSCachedTileLoader.getNewThreadPoolExecutor("Precache downloader"));
             }
+            requestedTiles = new ConcurrentSkipListSet<>(
+                    (o1, o2) -> String.CASE_INSENSITIVE_ORDER.compare(o1.getKey(), o2.getKey()));
+            for (LatLon point: points) {
+                TileXY minTile = tileSource.latLonToTileXY(point.lat() - bufferY, point.lon() - bufferX, currentZoomLevel);
+                TileXY curTile = tileSource.latLonToTileXY(CoordinateConversion.llToCoor(point), currentZoomLevel);
+                TileXY maxTile = tileSource.latLonToTileXY(point.lat() + bufferY, point.lon() + bufferX, currentZoomLevel);
+
+                // take at least one tile of buffer
+                int minY = Math.min(curTile.getYIndex() - 1, minTile.getYIndex());
+                int maxY = Math.max(curTile.getYIndex() + 1, maxTile.getYIndex());
+                int minX = Math.min(curTile.getXIndex() - 1, minTile.getXIndex());
+                int maxX = Math.max(curTile.getXIndex() + 1, maxTile.getXIndex());
+
+                for (int x = minX; x <= maxX; x++) {
+                    for (int y = minY; y <= maxY; y++) {
+                        requestedTiles.add(new Tile(tileSource, x, y, currentZoomLevel));
+                    }
+                }
+            }
+
+            this.totalCount = requestedTiles.size();
+            this.progressMonitor.setTicksCount(requestedTiles.size());
+
         }
 
@@ -1813,6 +1840,10 @@
             int processed = this.processedCount.incrementAndGet();
             if (success) {
-                this.progressMonitor.worked(1);
-                this.progressMonitor.setCustomText(tr("Downloaded {0}/{1} tiles", processed, totalCount));
+                synchronized (progressMonitor) {
+                    if (!this.progressMonitor.isCanceled()) {
+                        this.progressMonitor.worked(1);
+                        this.progressMonitor.setCustomText(tr("Downloaded {0}/{1} tiles", processed, totalCount));
+                    }
+                }
             } else {
                 Logging.warn("Tile loading failure: " + tile + " - " + tile.getErrorMessage());
@@ -1825,4 +1856,17 @@
         public TileLoader getTileLoader() {
             return tileLoader;
+        }
+
+        /**
+         * Execute the download
+         */
+        public void run() {
+            TileLoader loader = getTileLoader();
+            for (Tile t: requestedTiles) {
+                if (!progressMonitor.isCanceled()) {
+                    loader.createTileLoaderJob(t).submit();
+                }
+            }
+
         }
     }
@@ -1840,34 +1884,8 @@
      * @return precache task representing download task
      */
-    public AbstractTileSourceLayer<T>.PrecacheTask downloadAreaToCache(final ProgressMonitor progressMonitor, List<LatLon> points,
+    public AbstractTileSourceLayer<T>.PrecacheTask getDownloadAreaToCacheTask(final ProgressMonitor progressMonitor, List<LatLon> points,
             double bufferX, double bufferY) {
-        PrecacheTask precacheTask = new PrecacheTask(progressMonitor);
-        final Set<Tile> requestedTiles = new ConcurrentSkipListSet<>(
-                (o1, o2) -> String.CASE_INSENSITIVE_ORDER.compare(o1.getKey(), o2.getKey()));
-        for (LatLon point: points) {
-            TileXY minTile = tileSource.latLonToTileXY(point.lat() - bufferY, point.lon() - bufferX, currentZoomLevel);
-            TileXY curTile = tileSource.latLonToTileXY(CoordinateConversion.llToCoor(point), currentZoomLevel);
-            TileXY maxTile = tileSource.latLonToTileXY(point.lat() + bufferY, point.lon() + bufferX, currentZoomLevel);
-
-            // take at least one tile of buffer
-            int minY = Math.min(curTile.getYIndex() - 1, minTile.getYIndex());
-            int maxY = Math.max(curTile.getYIndex() + 1, maxTile.getYIndex());
-            int minX = Math.min(curTile.getXIndex() - 1, minTile.getXIndex());
-            int maxX = Math.max(curTile.getXIndex() + 1, maxTile.getXIndex());
-
-            for (int x = minX; x <= maxX; x++) {
-                for (int y = minY; y <= maxY; y++) {
-                    requestedTiles.add(new Tile(tileSource, x, y, currentZoomLevel));
-                }
-            }
-        }
-
-        precacheTask.totalCount = requestedTiles.size();
-        precacheTask.progressMonitor.setTicksCount(requestedTiles.size());
-
-        TileLoader loader = precacheTask.getTileLoader();
-        for (Tile t: requestedTiles) {
-            loader.createTileLoaderJob(t).submit();
-        }
+        PrecacheTask precacheTask = new PrecacheTask(progressMonitor, points, bufferX, bufferY);
+
         return precacheTask;
     }
Index: /trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackAction.java	(revision 14426)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackAction.java	(revision 14427)
@@ -60,5 +60,6 @@
         @Override
         protected void realRun() throws SAXException, IOException, OsmTransferException {
-            precacheTask = layer.downloadAreaToCache(progressMonitor, points, 0, 0);
+            precacheTask = layer.getDownloadAreaToCacheTask(progressMonitor, points, 0, 0);
+            precacheTask.run();
             synchronized (this) {
                 try {
