InvokeAsync mystery - exception while Show with the same window works fine

This forum is meant for questions and discussions about the X# language and tools
Post Reply
ic2
Posts: 1804
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

InvokeAsync mystery - exception while Show with the same window works fine

Post by ic2 »

I've tried to solve the below issue, so far without success.

I created a WPF window with on it one of the fancy Busy Indicators (some moving object, like a circle) from the Syncfusion library. Just before filling a DataGrid I open the window (from a C project within the same solution) where this moving object is on. This worked, but it only started moving when the whole datagrid was filled - the moment I would close it...

After trying a couple of Async changes without success, I asked Syncfusion support and they sent me a project using more or less my methods, also filling a datagrid -- and the object remained responsive from the start.

I implemented the code in my program which only differed in the way namespaces and classes were organized. And that directly gave a problem. See the code below, brought back to a minimum.

1 When I call window.Show the window appears without a problem (but nothing moves in it)
2 When I replaced it with the Syncfusion suggested await Application.Current.Dispatcher.InvokeAsync(() => window.Show()); I get an exception:

$exception {"Object reference not set to an instance of an object."} System.NullReferenceException
StackTrace " at IC2CSMethods.iConnectC.<ShowBusyWindow>d__13.MoveNext()

I really have no idea why this exception occurs in that InvoceAsync line while window.Show works fine, or what d__13.MoveNext() is supposed to be.

So I also don't know how to solve it. I tried reorganizing a few things in used namespace/class as this seems the only difference with the working (and moving) Syncfusion sample but without succes.

Does anybody have an idea what causes this and how to prevent that?

Code: Select all

		public async System.Threading.Tasks.Task ShowBusyWindow()
		//#s Show SyncFusion Busyindicator in small WPF window 4-4-2023
		{
            var window = new SFTools.BusyWindow();
            window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
			// Show the busy indicator on the UI thread
			await Application.Current.Dispatcher.InvokeAsync(() => window.Show());	// Nothing shows because of Object not set error
			// window.Show();													/ / This shows the window fine

		}
Dick
User avatar
robert
Posts: 4258
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

InvokeAsync mystery - exception while Show with the same window works fine

Post by robert »

Dick,
Without the rest of your code and without the example that works, it is difficult to explain this.
The only thing that I can think is that you need to add some code that gets called after the AWAIT.
or assign the result of the InvokeAsync call to a local
var _ = await .....
(_ is a special name for a discard variable that gets assigned a value but will not be used further in the code)

The d__13.MoveNext() method is related to the AWAIT keyword:
when your code contains an await statement, then the compiler generates a class that implements a state machine.
That name of the class is derived from the current method: In your case, that class is called IC2CSMethods.iConnectC.<ShowBusyWindow>.
The d__13.MoveNext() method switches that state machine from one state to another.
In your case, the first state of that machine will contain the code up to an until the await statement
The second state will contain the code after that the call to InvokeAsync().
In your example, there is NO code after the call to InvokeAsync(). Maybe that is the problem?

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
ic2
Posts: 1804
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

InvokeAsync mystery - exception while Show with the same window works fine

Post by ic2 »

Hello Robert,

Thank you for your reply. I have been looking a bit more into where what happens and eventually saw that Application.Current. was null, which caused the error. But why?
I found the answer to that on a 7 years old post. And as any Microsoft can rely on real issues never being solved I could apply the users solution. The problem happens when a WCF window is called from a Winforms window and can be solved by adding:

Code: Select all

if ( null == System.Windows.Application.Current )
{
   new System.Windows.Application();
}


See https://stackoverflow.com/questions/359 ... pplication

Unfortunately, now everything works, the reason I all started this is far from solved. Also not in the full sample Syncfusion sent. They fill a DataGrid with an OC (I added one line of that below) and then use await Task.Delay(5000); with comment // Wait for a short duration to give enough time for the busy indicator to be noticeable

It all looks as if it works. You see a moving busy indicator and then the DataGrid is filled. But that is only cosmetic. In the code below I added a FOR loop to add many more items. And what happens then? During the 5 seconds wait the BusyIndicator moves allright. But once the 200.000 (x32 Employee Names in the original code) add commands take place, which takes 8 seconds on my Pc, the BusyIndicator stops moving immediately and doesn't move until the DataGrid is filled.

So even with all Awaits & Asyncs & Tasks, created by what I suppose a knowledgeable support specialist from Syncfusion in 2023 it seems impossible for a Pc to have a moving indicator while filling data. That it works on a Delay command is not so interesting for my users :(

It's quite frustrating though...

Code: Select all

        public async Task<ObservableCollection<Model>> GetRecords()
        {
            var gdcsource = new ObservableCollection<Model>();
            this.BusyIndicatorWindow();
			await Task.Delay(5000);
			for(int i = 0;i<200000;i++)
			{
				gdcsource.Add(new Model() { EmployeeName="Robert",EmployeeArea="Torino",EmployeeDesignation="Analysts",EmployeeSalary=10000,EmployeeGender="Male" });
Dick
Post Reply