I created the function GetMapImage() based on the sample codes provided. It works very well with one client application. But now when I test my web server with two clients and when I pan the maps almost simultaneously, an exception is raised and my client program crashes. I found out that the crash happens when the function MapEngine.DrawStaticLayers() is called
I think as you said, this problem will happen ONLY when more than 1 clients will access the server. When one of the clients closes the layer, the other clients may be trying to draw it while finding the layers is closed.
So, I think 2 solutions for your problems. 1) Try to make asynchronous access for your server that is to say that, guarantee only one client access the server at one time. 2) DONOT close the layers at server side.
I chose the 2nd solution provided by you so now I don’t close my layers at server side. However, it still raises an exception when I pan my maps simultaneously. I want my server to be accessed by more than 1 client at a time.
Which version you are using? Did you use the latest public release version of Service Edition 3.1.182 or some other version (3.0.124)?
We did some tests against it as following: we setup a server which deals with clients request, we use 2 clients to send request with a timer tick set differently but still failed to recreate it.
try { if (appHash["Open_NA"] == null) { TempmapEngine = (MapEngine)appHash["NA_mapEngine"];
TempmapEngine.OpenAllLayers(); < ----- This is the only place that opens all the layers (only gets called on first open)
appHash["Open_NA"] = 1; < ----- when I check this break point before open layers all layers isOpen = false } switch (layerName.ToUpperInvariant())
{ case "RICHMOND": TempmapEngine = (MapEngine)appHash["NA_mapEngine"]; < ----- break point isopen for each layer = true break; default: TempmapEngine = new MapEngine(); break; }
strTest = "Error draw Shape MSG: " + ex.Message; < --- error message when more then one connection "Error draw Shape MSG: Object is currently in use elsewhere." } }
You mentioned you set up the a web server and send client requests by using timers. Can I have your code for reference?
Thanks for the sample code. Regarding the executing of CloseAllLayers(), we know how that works.
our main issue is with the DrawStaticLayers. We want to know how we can modify our code to be able to simultaneously draw different bitmaps. In your sample code you used lock() function, which we have tried before, but that would prevent simultaneously drawing from mapengine.
also note that our shape file is open as readonly.
The solution for this you should create a MapEngine every time a request comes in, while currently , what you have done is probably shared the same “MapEngine” to draw bitmaps for different clients requests comes in, whiles the MapEngine have to keep its own properties.
1) the above solution, is something we did in the first test run... but found that adding each layer to the MapEngine every time slows down the loading process. so changed our implementation to using single open layer process. Is there something else that we can do to speed up creating new MapEngine with every client call?
2) question: if we use the above solution can we initialize all layers globally, then each client request, create a new MapEngine and add the globally defined layers into the new MapEngine?
e.g.
if (appHash["Open_NA"] == null)
{
ShapeFileFeatureLayer layer = null;
layer = new ShapeFileFeatureLayer(shpfileName, ShapeFileReadWriteMode.ReadOnly);
I did not see you attachment “mapstuff.jpg” in your previous post :-)
3 things I want to clear up here hope it helps.
1) In the above solution, we still cannot share the shape file layers or raster layers as you try to define globally, while if it is GoogleLayer or VELayer , probably it could.
The reason is that in the shape file, we will keep of bunch of stream (.shp, .shx, .dbf, .idx & .ids), we should keep the stream unique for each layer.
2) We tested that it would probably slow down about 10% for the loading process every time.
3) If we can have one MapEngine for each client, then we can call the CloseAllLayers after its drawing finish.