arcgis wpf: QueryTask Crashes on query completed net 4.0 big solution

3409
10
02-04-2014 02:24 AM
Labels (1)
DamirImangulov
New Contributor
Product: ArcGis 10.2 WPF Runtime

Hi, I'm using Featurelayer. On computers with NET 4.5 everything works fine. But computers NET 4.0 is an error.

Catching Unhandled exception
System.AggregateException: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread. ---> System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
at System.Windows.Threading.Dispatcher.VerifyAccess()
at System.Windows.DependencyObject.GetValue(DependencyProperty dp)
at ESRI.ArcGIS.Client.GraphicsLayer.<Graphics_Collectionchange d>b__1(Graphic a)
at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at ESRI.ArcGIS.Client.GraphicsLayer.Graphics_Collectionchange d(Object sender, NotifyCollectionchange dEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionchange d(NotifyCollectionchange dEventArgs e)
at ESRI.ArcGIS.Client.GraphicCollection.AddRange(IEnumerable`1 items)
at ESRI.ArcGIS.Client.FeatureLayer.task_QueryComplete(Object sender, QueryEventArgs args)
at ESRI.ArcGIS.Client.Tasks.QueryTask.OnExecuteCompleted(QueryEventArgs args)
at ESRI.ArcGIS.Client.Tasks.QueryTask.<>c__DisplayClassf.<ExecuteAsync>b__d(Task`1 result)
at ESRI.ArcGIS.Client.Tasks.TaskBase.<>c__DisplayClassc`1.<HandeEventBasedTask>b__a(Task`1 result)
at System.Threading.Tasks.Task`1.<>c__DisplayClass17.<ContinueWith>b__16(Object obj)
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.Execute()

and so on ...

The most interesting cases looked similar to the network, I'm not the first to face such a problem, but to repeat it in a small decision can not.

Disassembled assembly ArcGis proved that there QueryTask class call the base class.

public void ExecuteAsync(Query query, object userToken = null)
        {
            Action<Task<QueryResult>> isFaulted = (Task<QueryResult> result) => {
                if (result.IsFaulted)
                {
                    this.LastResult = null;
                    return;
                }
                this.LastResult = result.Result.FeatureSet;
                QueryEventArgs queryEventArg = new QueryEventArgs(result.Result.FeatureSet, result.Result.ExceededTransferLimit, userToken);
                this.OnExecuteCompleted(queryEventArg);
            };
            base.HandeEventBasedTask<QueryResult>((CancellationToken ct) => this.ExecuteTaskAsync(query, ct), Resources.QueryTask_Error, isFaulted, userToken);
        }

HandeEventBasedTask turns out he is responsible for returning to the desired flow! and what we see inside the method

taskToExecute(token).ContinueWith((Task<R> result) => {
                    ... some code
                }, TaskScheduler.FromCurrentSynchronizationContext());

To return to the calling thread is used method TaskScheduler.FromCurrentSynchronizationContext (), but there's a bug in NET 4.0, NET 4.5 and all perfectly fulfills.

Help please, you only need to change this piece of code that all worked perfectly in both fremvork. If I need help with those kind of logic there references.

!!! reproduced
0 Kudos
10 Replies
DamirImangulov
New Contributor
this project show different behavior on 4.5 and 4.0 framework. On 4.5 all work fine, in 4.0 crashes
0 Kudos
DavidLednik
Occasional Contributor II
Hi,

I can ran the sample without any issues on .NET 4.0

Is there anything special I need to do with the app to crash?
Also there is no QueryTask in the code. Are you saying QueryTask crashes inside FeatureLayer?

regards,
David
0 Kudos
DamirImangulov
New Contributor
Hello, you must run project without installed net 4.5, i test it on win7 and winXP. if you test project on pc with installed vs2012, for example, it will work perfectly, because net 4.5 it is part of vs2012. i create clean virtual machine with windows xp, build project with vs 2012, then copy bin folder to virtual machine. When project start i'm change zoom and project crashes, after few seconds.

I don't use query task. I'm decompile your assembly ESRI.ArcGIS.Client.dll. FeatureLayer when update method called, uses QueryTask to load data from service. QueryTask for synchronization with current execution context uses fromcurrentsynchronizationcontext method this method not work in net 4.0 sometime.

if you do all as i saw, and all will right, i will send to you another example, maybe allready compiled.

I will wait respond from you.
Thanks for your help, it is matter for me and my job 😉
0 Kudos
DavidLednik
Occasional Contributor II
I don't have a machine with that specs available atm.

If you manually install .NET 4.5 on a machine with exception does it go away?
If it does. Any reason why you can't use it as a workaround?


David
0 Kudos
DamirImangulov
New Contributor
Reason why i use net 4.0 - it is technical requirements. Many of our customers use windows XP. Net 4.5 can not be installed on windows XP.

In yours system requirements i found this:

Supported Operating System

Windows 8.1 Basic, Professional and Enterprise (32 bit and 64 bit [EM64T])*
Windows 8 Basic, Professional and Enterprise (32-bit and 64-bit [EM64T])*
Windows 7 Ultimate, Enterprise, Professional, Home Premium (32-bit and 64-bit [EM64T])*
Windows Vista Ultimate, Enterprise, Business, Home Premium (32-bit and 64-bit [EM64T])
Windows XP Professional Edition, Home Edition (32-bit)
Windows XP Professional Edition, Home Edition (64-bit [EM64T])

It is bug. What we will do?
You can create simple virtual machine under hyper-v, can found this in, as example in windows 8.
Help me with this, i am not first, who found this bug.
0 Kudos
MichaelBranscomb
Esri Frequent Contributor
Hi,

The issues seems to be the way in which you are adding controls to the UI.

In your example I changed the following code:

private void FrameworkElement_OnLoaded(object sender, RoutedEventArgs e)
{
    System.Diagnostics.Trace.CorrelationManager.StartLogicalOperation("LogicalOperation");

    Task.Factory.StartNew(() => { });
    Task.Factory.StartNew(() => { })
        .ContinueWith(t => { }, TaskScheduler.FromCurrentSynchronizationContext());
    Task.Factory.StartNew(() => { })
        .ContinueWith(t => { }, TaskScheduler.Default);
    var g = (Grid) sender;
    var v = new GisPreviewView();
    g.Children.Add(v);

    System.Diagnostics.Trace.CorrelationManager.StopLogicalOperation();
}


To just:

private void FrameworkElement_OnLoaded(object sender, RoutedEventArgs e)
{
    var g = (Grid)sender;
    if (g.Dispatcher.CheckAccess())
    {
        var v = new GisPreviewView();
        g.Children.Add(v); 
    }
}


And I did not see any threading issues (on Windows XP SP3 x86 with .NET 4.0 (4.0.30319)). Actually the CheckAccess call is not required, but it was just for good measure.

Is that a feasible solution for you?

Cheers

Mike
0 Kudos
DamirImangulov
New Contributor
You're right in the program hello world level, everything works fine. But our program another level. Our solution includes services, a lot of rich interface.

private void FrameworkElement_OnLoaded(object sender, RoutedEventArgs e)
{
    System.Diagnostics.Trace.CorrelationManager.StartLogicalOperation("LogicalOperation");

    Task.Factory.StartNew(() => { });
    Task.Factory.StartNew(() => { })
        .ContinueWith(t => { }, TaskScheduler.FromCurrentSynchronizationContext());
    Task.Factory.StartNew(() => { })
        .ContinueWith(t => { }, TaskScheduler.Default);
    var g = (Grid) sender;
    var v = new GisPreviewView();
    g.Children.Add(v);

    System.Diagnostics.Trace.CorrelationManager.StopLogicalOperation();
}


Bold lines of code - this is what happens in the WCF. This small project to demonstrate the errors, I send you an example in which the error is repeated. Before i wrote to you, I spent a week in order to get around the bug and have read many forums. This is a bug. This does not get around. Your code should check that the synchronization context not null, and if it null, then the code should use Taskscheduler.Default to synchronize with UI thread.
0 Kudos
MichaelBranscomb
Esri Frequent Contributor
Hi,

Thankyou for the additional information. After following your research I have entered this issue as a bug. I'll update the post with more information when it becomes available.

Cheers

Mike
0 Kudos
DamirImangulov
New Contributor
Hello 10 days ago you said that you write as soon as you will find solution, you can say anything about the date of correction?
0 Kudos