POST
|
awaiting LayersLoadedAsync before doing any layer moves appears to avoid the issue, but I am not 100% sure I have not seen the issue when adding or removing layers. It only has manifested itself when moving layers.
... View more
06-03-2016
09:35 AM
|
0
|
0
|
1176
|
POST
|
When reordering layers, even those that are not the ones loading, it is possible to hit this exception. Note that the spatial reference was already set on the map view. Sample callstack: at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) at System.Collections.Generic.List`1.Insert(Int32 index, T item) at Esri.ArcGISRuntime.Controls.CoreLayerCollection.MoveLayer(Layer layer) at Esri.ArcGISRuntime.Controls.ViewBase.HandleLayersMoved(CoreLayerCollection layerManager, IEnumerable`1 movedLayers) at Esri.ArcGISRuntime.Controls.ViewBase.<OnLayersChanged>d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Esri.ArcGISRuntime.Controls.ViewBase.<OnLayerCollectionChanged>d__41.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.<ThrowAsync>b__6_0(Object state) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.DispatcherOperation.InvokeImpl()
... View more
06-03-2016
09:02 AM
|
1
|
11
|
4065
|
POST
|
The two layers shown are these: World_Street_Map (MapServer) Maritime Chart Server: WMSServer Note they do not line up.
... View more
06-02-2016
08:51 AM
|
0
|
0
|
1459
|
POST
|
See runtime freezes sometimes when zooming on S57 layer -- bug or incorrect api usage? for one way to get to this state.
... View more
06-01-2016
06:11 AM
|
0
|
0
|
377
|
POST
|
Once the runtime enters this bad state, it is then possible to freeze the entire application: Occasional hangs in the runtime Our tests show that it is most likely to occur when there are multiple zoom operations in flight. Also, it is more likely when running on a lower powered or otherwise burdened computer. That sounds like a concurrency bug: the operations on a slower computer take longer to complete and increase the chances of revealing the unhappy collision/overlap.
... View more
06-01-2016
06:10 AM
|
0
|
4
|
2157
|
POST
|
I ended up writing my own rendering stack. The performance was good enough despite some cumbersome code to interface with the runtime. In some experiments, my solution used 50% memory for 15x the data. I think a generic "geometry layer" (just drawing primitives, no hit testing or other support) solution from Esri could easily see 6x improvement in memory usage over graphics layer.
... View more
06-01-2016
06:05 AM
|
0
|
0
|
434
|
POST
|
another (abbreviated) main stack. This one is not blocked on a join. 00000000`004ac948 000007fe`fcee10ac : 00000000`3de0efb0 ffffffff`fffffffe 00000000`26b899c0 00000000`3cb2b680 : ntdll!ZwWaitForSingleObject+0xa 00000000`004ac950 000007fe`d79fc07b : 00000000`1fea8ef0 00000000`00000000 00000000`00000000 00000000`0000085c : KERNELBASE!WaitForSingleObjectEx+0x79 00000000`004ac9f0 000007fe`d79f94de : 00000000`1fea8ef0 000007fe`f14ecfb4 00000000`254217e0 00000000`00000000 : RuntimeCoreNETDesktop!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::find+0x7e55b 00000000`004aca40 000007fe`d7a4d510 : 00000000`004acaa0 00000000`00000000 00000000`00000000 00000000`00000000 : RuntimeCoreNETDesktop!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::find+0x7b9be 00000000`004aca80 000007fe`d7a4b650 : 00000000`1ff1d220 00000000`004acbd8 00000000`25421750 00000000`1ff1d210 : RuntimeCoreNETDesktop!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::erase+0x1a920 00000000`004acb50 000007fe`d7a6ba6f : 00000000`25421750 00000000`23b11260 00000000`25421750 00000000`00000000 : RuntimeCoreNETDesktop!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::erase+0x18a60 00000000`004acba0 000007fe`d798d0c9 : 00000000`004ad530 00000000`27611450 00000000`23b11260 000007fe`d8ba2288 : RuntimeCoreNETDesktop!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::erase+0x38e7f 00000000`004acc20 000007fe`d7985213 : 00000000`27bb09a8 00000000`27bb09a8 00000000`27bb09a8 00000000`23b11260 : RuntimeCoreNETDesktop!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::find+0xf5a9 00000000`004acc50 000007fe`d77bea63 : 000007fe`ebe6fc80 000007fe`8c7693a0 00000000`25786310 ffffffff`fffffffe : RuntimeCoreNETDesktop!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::find+0x76f3 00000000`004accd0 000007fe`8c955a6c : 000007fe`8c768470 00000000`25786310 00000000`0061b530 00000000`25786310 : RuntimeCoreNETDesktop!MapRemoveLayerAt+0xd3
... View more
05-25-2016
11:05 AM
|
0
|
0
|
377
|
POST
|
I've been debugging some sporadic hangs. I found one problem (which may lead to others!) A thread join is executed on the main thread. Unfortunately, this means an infinite wait. The join implementation looks something like this: int _Thrd_join(_Thrd_t thr, int *code) { /* return exit code when thread terminates */ unsigned long res; if (WaitForSingleObjectEx(thr._Hnd, INFINITE, FALSE) == WAIT_FAILED || GetExitCodeThread(thr._Hnd, &res) == 0) return (_Thrd_error); if (code) *code = (int)res; return (CloseHandle(thr._Hnd) == 0 ? _Thrd_error : _Thrd_success); } Note the WaitForSingleObjectEx with an INFINITE timeout. Callstack for main thread: 00000000`0052dd68 000007fe`fd4310ac ntdll!ZwWaitForSingleObject+0xa 00000000`0052dd70 000007fe`e680cb34 KERNELBASE!WaitForSingleObjectEx+0x79 00000000`0052de10 000007fe`e69716e1 msvcp120!_Thrd_join+0x1c 00000000`0052de40 000007fe`e6971093 RuntimeCoreNETDesktop!UnitEquals+0x1091 00000000`0052de90 000007fe`e6971e48 RuntimeCoreNETDesktop!UnitEquals+0xa43 00000000`0052ded0 000007fe`8f197ab7 RuntimeCoreNETDesktop!DrawSurfaceShutdownDrawThread+0xc8 00000000`0052df40 000007fe`8f48a515 0x000007fe`8f197ab7 00000000`0052dff0 000007fe`8f35c997 0x000007fe`8f48a515 00000000`0052e020 000007fe`8f35cb48 0x000007fe`8f35c997 00000000`0052e050 000007fe`eb7112d0 0x000007fe`8f35cb48 00000000`0052e090 000007fe`eb6f54f6 PresentationCore_ni!`string'+0x14ef08 00000000`0052e140 000007fe`ea3c8058 PresentationCore_ni!`string'+0x13312e 00000000`0052e1a0 000007fe`ea2f13b1 PresentationFramework_ni+0x538058 00000000`0052e230 000007fe`eb728e26 PresentationFramework_ni+0x4613b1 00000000`0052e290 000007fe`eb70dca5 PresentationCore_ni!`string'+0x166a5e 00000000`0052e2c0 000007fe`eb70dbb1 PresentationCore_ni!`string'+0x14b8dd 00000000`0052e300 000007fe`eb70d93c PresentationCore_ni!`string'+0x14b7e9 00000000`0052e350 000007fe`eb70d822 PresentationCore_ni!`string'+0x14b574 00000000`0052e3c0 000007fe`ef2d1769 PresentationCore_ni!`string'+0x14b45a 00000000`0052e410 000007fe`ef2d1666 WindowsBase_ni+0x121769 00000000`0052e480 000007fe`ef2d463b WindowsBase_ni+0x121666 00000000`0052e4d0 000007fe`ed30ad2e WindowsBase_ni+0x12463b 00000000`0052e550 000007fe`ed30abc7 mscorlib_ni+0x52ad2e 00000000`0052e620 000007fe`ed30ab82 mscorlib_ni+0x52abc7 00000000`0052e650 000007fe`ef2d439e mscorlib_ni+0x52ab82 00000000`0052e6a0 000007fe`ef2cf762 WindowsBase_ni+0x12439e 00000000`0052e710 000007fe`ef2cfba1 WindowsBase_ni+0x11f762 00000000`0052e790 000007fe`ef2d19f3 WindowsBase_ni+0x11fba1 00000000`0052e810 000007fe`ef2d1922 WindowsBase_ni+0x1219f3 00000000`0052e8a0 000007fe`ef2d1769 WindowsBase_ni+0x121922 00000000`0052e8f0 000007fe`ef2d1666 WindowsBase_ni+0x121769 00000000`0052e960 000007fe`ef2cf0d1 WindowsBase_ni+0x121666 00000000`0052e9b0 000007fe`ef2d108f WindowsBase_ni+0x11f0d1 00000000`0052ea50 000007fe`ef49202a WindowsBase_ni+0x12108f 00000000`0052eb00 000007fe`ee2d0b4e WindowsBase_ni+0x2e202a 00000000`0052eb70 00000000`77439c11 clr!UMThunkStub+0x6e 00000000`0052ec00 00000000`7743992a user32!UserCallWinProcCheckWow+0x1ad 00000000`0052ecc0 000007fe`ef300518 user32!DispatchMessageWorker+0x3d0 00000000`0052ed50 000007fe`ef2e555c WindowsBase_ni+0x150518 00000000`0052ee10 000007fe`ea255ad3 WindowsBase_ni+0x13555c 00000000`0052eea0 000007fe`ea2558bd PresentationFramework_ni+0x3c5ad3 00000000`0052eee0 000007fe`8ec504e8 PresentationFramework_ni+0x3c58bd 00000000`0052ef40 000007fe`ee2b3883 0x000007fe`8ec504e8 00000000`0052ef90 000007fe`ee2b3745 clr!CallDescrWorkerInternal+0x83 00000000`0052efd0 000007fe`ee2b3cf6 clr!CallDescrWorkerWithHandler+0x4e 00000000`0052f010 000007fe`ee3cedc8 clr!MethodDescCallSite::CallTargetWorker+0xf8 00000000`0052f110 000007fe`ee3cef6a clr!RunMain+0x1e7 00000000`0052f2f0 000007fe`ee3cee58 clr!Assembly::ExecuteMainMethod+0xb6 00000000`0052f5e0 000007fe`ee3cf000 clr!SystemDomain::ExecuteMainMethod+0x5ea 00000000`0052fc10 000007fe`ee3cf0c6 clr!ExecuteEXE+0x3f 00000000`0052fc80 000007fe`ee3e12d0 clr!CorExeMainInternal+0xb2 00000000`0052fd10 000007fe`f0008389 clr!CorExeMain+0x14 00000000`0052fd50 000007fe`f00a5b21 mscoreei!CorExeMain+0xe0 00000000`0052fda0 00000000`773159ed mscoree!CorExeMain_Exported+0x57 00000000`0052fdd0 00000000`7754b371 kernel32!BaseThreadInitThunk+0xd 00000000`0052fe00 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
... View more
05-25-2016
10:33 AM
|
0
|
2
|
2373
|
POST
|
Hi Mike, that did the trick. After "awaiting", I can party on the buffer with no ill consequence. Here is some more context in case others run into my problem: I was using a MemoryStream. I could only get it to work with SetSource and not with SetSourceAsync because I forgot to set the seek point on the stream to the beginning before passing it to SetSourceAsync. From my testing, the operation is async with both SetSource and SetSourceAsync. SetSourceAsync just allows to monitor when that async operation completes. Because the operation is async, I noticed an occasional error when I would write to the stream right away after passing it to SetSource because I was writing data that the runtime was reading at the same time.
... View more
05-02-2016
11:05 AM
|
1
|
0
|
356
|
POST
|
PictureMarkerSymbol.SetSource Method If it is possible, I would like to reuse the buffer. However, without knowing when the runtime is "done" reading from it, I don't know when it is safe. I already verified that the buffer is not read from right away by writing to it immediately after setting it. Also, I saw that SetSource executes superfast (microseconds on my machine) lending further evidence that it is probably not doing any decoding right away. Why do I want to reuse the buffer? I want to create less garbage (and hence GC pressure). I am attempting to use the PictureMarkerSymbol as a way to include general raster content generated on the fly. I am writing my own renderer that draws to a bitmap, encodes it, and then sends it to the runtime. Yes, this is very awkward, but the other runtime APIs do not satisfy my use case. See draw a million or more small lines. data set updated at 1-10Hz
... View more
04-29-2016
05:38 AM
|
0
|
2
|
3211
|
POST
|
Hi Antti, I'll provide some examples below. There's more. I've written more than a thousand lines of workarounds last week and it is hard to keep track of it all! Another strange behavior I uncovered was the map view extent going null when the map center is set to NaN. Granted, NaN is nonesense, but SetViewAsync should complain/throw right away instead. The NaN made it to the map view because of innocent looking code like this: static async void TestExtentAndSetView(MapView map, MapPoint point) { var p = Project(NormalizeCentralMeridian(point), map.SpatialReference); var extent = NormalizeCentralMeridian(map.Extent); if (!Within(p, extent)) { try { await map.SetViewAsync(point, TimeSpan.FromSeconds(1.5)); } catch (Exception ex) { /*log the error*/ } } } I have since switched over to my own "envelope" and "projection" code that is easier to use and get right. GeometryEngine.Project static MapPoint EsriProject(double lat, double lon) { return (MapPoint)GeometryEngine.Project(new MapPoint(lon, lat, SpatialReferences.Wgs84), SpatialReferences.WebMercator); } static MapPoint EsriUnProject(double x, double y) { return (MapPoint)GeometryEngine.Project(new MapPoint(x, y, SpatialReferences.WebMercator), SpatialReferences.Wgs84); } public void Test() { Action<double> xNaN = lon => Assert.IsTrue(double.IsNaN(EsriProject(0, lon).X)); xNaN(-180); xNaN(180); xNaN(-179.99999); xNaN(179.99999); } const double Wgs84EarthSemiMajorRadiusMeters = 6378137; const double webMercatorMaxX = Wgs84EarthSemiMajorRadiusMeters * System.Math.PI; var p1 = EsriUnProject(webMercatorMaxX, 0); var p2 = EsriUnProject(-webMercatorMaxX, 0); System.Console.WriteLine(p1); // prints MapPoint[X=NaN, Y=NaN, Wkid=4326] System.Console.WriteLine(p2); // prints MapPoint[X=NaN, Y=NaN, Wkid=4326] Envelopes, Polyline, etc Envelope unions do simple min/max and do not handle the wrap around. That means that the a union operation may connect the long way across the world when the intent is the short way. I've written my own "GeoRect" code that has a well defined left and right and can handle the wraparound. In other places, I do something like this: static void FixXsForEsri(ref double x1, ref double x2, double y1, double y2, double expectedLength) { var distSqd = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1); bool simpleConnectWouldBeTheLongWayAcrossTheWorld = distSqd > expectedLength * expectedLength * 2.0; if (simpleConnectWouldBeTheLongWayAcrossTheWorld) { // Map X on negative side of the projection origin to the right. if (x2 < 0.0) x2 += GeoRectMaxBounds.WebMercator.Width; else if (x1 < 0.0) x1 += GeoRectMaxBounds.WebMercator.Width; } } I can see how the way Envelope behaves could be more renderer friendly. Simple min/max-ing is less "branchy" than the wrap test code. From a map API user's view, it is quite unfriendly. Simple Repro: var p1 = new MapPoint(179, 0, SpatialReferences.Wgs84); var p2 = GeometryEngine.GeodesicMove(p1, 1e3, LinearUnits.Kilometers, 90); var e1 = new Envelope(p1, p1); var e2 = new Envelope(p2, p2); System.Console.WriteLine(e1.Union(e2).Width); // prints 351.016847158805 degrees !!
... View more
04-25-2016
10:39 AM
|
0
|
0
|
445
|
POST
|
I've worked through many of the issues by just avoiding the GeometryEngine and using my own implementations instead. To make lines connect correctly, I test if a simple planar connect would be too long and if so, I adjust the "left" point to be the right by adding the width of the WebMercator projection before supplying the points to the runtime.
... View more
04-25-2016
08:30 AM
|
0
|
0
|
445
|
POST
|
Thanks for the quick response, Mike. In our actual code we filter duplicates. We've also now limited the max number of S57s to 9 and prevented removing of the layers until they are loaded in order to reduce (but not eliminate) the chances of the problem. The sample posted code was a small example that reproduces the sporadic freezes we've seen of the map view. We've noticed the map view freeze when zooming to an S57 layer's extent and more rarely when trying to remove a layer. Since it is so sporadic, our only speculation at this time is a concurrency/timing hazard in the runtime (unless we are using the APIs wrong unknowingly?). When the runtime freezes, it might as well be dead from the user's perspective. No interaction (pan, zoom) is possible with the map. In this attached screenshot, the map has been unresponsive for more than 5 minutes. The black is from the outline of an S57 layer. It died while zooming in and got frozen when the black part of the outline was on screen. I've also gotten the app to actually crash. Technique to help reproduce: scroll the mouse scroll wheel back and forth like a maniac while the S57s are loading. Yes, this is not normal user behavior, but it helps trigger the issue which happens rarely otherwise and is hard to track down.
... View more
04-25-2016
05:51 AM
|
0
|
1
|
2157
|
POST
|
The application remains responsive and does not die. The map view, however, stops accepting user input and appears frozen. We've seen this sporadically. Below is a small sample that reproduces the problem. Note you may have to run it a few times before it occurs; the issue does not happen every time. <Window x:Class="Sample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:esri="http://schemas.esri.com/arcgis/runtime/2013" Title="esri sample" Height="350" Width="525"> <Grid> <esri:MapView x:Name="MyMapView"> <esri:Map x:Name="TheMap"> <esri:ArcGISTiledMapServiceLayer ServiceUri="http://services.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer" /> </esri:Map> </esri:MapView> </Grid> </Window> using Esri.ArcGISRuntime.Geometry; using Esri.ArcGISRuntime.Hydrographic; using System.Collections.Generic; using System.Windows; namespace Sample { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var center = (MapPoint)GeometryEngine.Project(new MapPoint(-80.1, 26.1, SpatialReferences.Wgs84), SpatialReferences.WebMercator); MyMapView.SetView(center, 30000); SingleMapRepeat(); //MultiMapRepeat(); } private void SingleMapRepeat() { //Wait for the zoomed area, most likely to see frozen. If not, increase the repeat number. int repeat = 9; MyMapView.LayerLoaded += Zoom; AddS57("../../../../../../s57/US5FL32M/ENC_ROOT/US5FL32M/US5FL32M.000", repeat); } private void MultiMapRepeat() { //start to see frozen when repeat is 3. If not, increase the repeat number. Pan or manually zoom may increase the chance to make the map frozen. int repeat = 3; MyMapView.LayerLoaded += Zoom; AddS57("../../../../../../s57/US5FL32M/ENC_ROOT/US5FL32M/US5FL32M.000", repeat); AddS57("../../../../../../s57/US4MA23M/ENC_ROOT/US4MA23M/US4MA23M.000", repeat); AddS57("../../../../../../s57/US3NY01M/ENC_ROOT/US3NY01M/US3NY01M.000", repeat); AddS57("../../../../../../s57/US1GC09M/US1GC09M.000", repeat); AddS57("../../../../../../s57/US2EC01M/US2EC01M.000", repeat); AddS57("../../../../../../s57/US3FL30M/US3FL30M.000", repeat); AddS57("../../../../../../s57/US4AL12M/US4AL12M.000", repeat); AddS57("../../../../../../s57/US5FL4AM/US5FL4AM.000", repeat); AddS57("../../../../../../s57/US5AL12M/US5AL12M.000", repeat); } private void AddS57(string path, int repeat) { for (int i = 0; i < repeat; i++) { var layer = new HydrographicS57Layer() { Path = path }; layer.DisplayName = path; TheMap.Layers.Add(layer); System.Console.WriteLine("add layer " + layer.DisplayName); } } async void Zoom(object _, Esri.ArcGISRuntime.Controls.LayerLoadedEventArgs e) { System.Console.WriteLine("zoom layer " + e.Layer.ID + " " + e.Layer.FullExtent.Extent.XMin + " " + e.Layer.FullExtent.Extent.YMin); await MyMapView.LayersLoadedAsync(new Esri.ArcGISRuntime.Layers.Layer[] { e.Layer }); await MyMapView.SetViewAsync(e.Layer.FullExtent); } } }
... View more
04-22-2016
05:58 AM
|
0
|
8
|
5377
|
Title | Kudos | Posted |
---|---|---|
1 | 06-03-2016 09:02 AM | |
1 | 05-02-2016 11:05 AM |
Online Status |
Offline
|
Date Last Visited |
11-11-2020
02:23 AM
|