0

So I am having an issue with C# async and await. I have 2 long running functions that I want to call asynchronously onLoad on a Windows Forms Application. I encapsulated them in 2 async functions. One gets the Timezones and the other gets the Aggregates. The issue is the data somehow is colliding. These are the functions:

private async void LoadAggregates()
        {
            //Load Available Aggregates
            Task<CanaryAggregate> caTask = GetAggregatesAsync();
            CanaryAggregate ca = await caTask;
            Dictionary<string, dynamic> Aggs = ca.aggregates;

            foreach (KeyValuePair<string, dynamic> item in Aggs/*PropertyDescriptor pd in TypeDescriptor.GetProperties(ca.aggregates)*/)
            {
                cbAggregate.Items.Add(item.Key);
            }

            cbAggregate.SelectedIndex = cbAggregate.FindStringExact(Properties.Settings.Default.Aggregate);
        }

        private async Task<CanaryAggregate> GetAggregatesAsync()
        {
            CanaryAggregate ca = null;
            await Task.Run(() =>
            {
                ca = Program.caAPI.getAggregates();
            });
            return ca;
        }
        private async void LoadTimeZones()
        {
            //Load the TimeZones
            Task<CanaryTimezone> ctzTask = GetTimezoneAsync();
            CanaryTimezone ct = await ctzTask;
            for (int i = 0; i < ct.timeZones.Length; i++)
            {
                ToolStripMenuItem tssmiTimezone = new ToolStripMenuItem();
                tssmiTimezone.Text = ct.timeZones[i];
                tssmiTimezone.Click += new EventHandler(TimezoneChanged);
                tssbTimezone.DropDownItems.Add(tssmiTimezone);
            }
        }
        private async Task<CanaryTimezone> GetTimezoneAsync()
        {
            CanaryTimezone ct = null;

           await Task.Run(() =>
            {
                ct = Program.caAPI.getTimezones();

            });
            return ct;
        }

Somehow the returned data from GetAggregates is being sent back to the data of GetTimezones. And then GetTimezones is throwing a NullReferenceException on the ct.timeZones.length part. I output the data I am receiving from the Program.caAPI.getTimeZones(), and I am getting the aggregate data in that function. When I don't use async await I am receiving the correct data. I don't know why this is happening at all.

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
Abedjoud
  • 23
  • 3
  • _"Somehow the returned data from GetAggregates is being sent back to the data of GetTimezones."_ - I don't believe you. Anyway, your code doesn't seem to show enough information. We don't see how any of these methods are being called. Also, if `getTimeZones()` and `getAggregates()` are network/IO-bound methods, why aren't they async? – ProgrammingLlama Apr 01 '21 at 02:58
  • Could you show us how this methods are used? I think the problem should be there since the methods doesn't seem to share any data between them – Roberto Langarica Apr 01 '21 at 03:06
  • Don't do `async void` unless it is for event handlers. In all other circumstances use `async Task`. – Enigmativity Apr 01 '21 at 03:55

1 Answers1

-1

Remove async from GetAggregatesAsync and GetTimezoneAsync.

private CanaryAggregate GetAggregates()
{
    CanaryAggregate ca = Program.caAPI.getAggregates();
    return ca;
}
tymtam
  • 31,798
  • 8
  • 86
  • 126