Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
168 views
in Technique[技术] by (71.8m points)

c# - Task never reaching its end

I am trying to run a task and it seems to never reach its end, getting stuck. I would usually suspect an infinite loop, but there is no loop this time. This code is running on an android device, under xamarin forms.

First, here's the task that end up locking.

public static async Task<InventoryItem> GetTaskInventory(string labeladresse)
        {
            InventoryItem result = null;
            await Task.Run(() =>
            {
                try
                {
                    IDeliveryService client = Common.GetDeliveryService();
                    result = client.GetLineTaskInventory(labeladresse);
                }
                catch (Exception ex)
                {
                    LogError(ex);
                }
                finally
                {
                }
            }).ConfigureAwait(false); ;

            return result;
        }

Pretty simple, it calls a service (service is working) and get some result.

Second, here's a portion of where it's called (from a viewmodel):

async Task ExecuteLoadItemsCommand()
        {
            [...]
            else
                {
                    IsBusy = true;

                    primaryBin.inventoryItem = await Common.GetTaskInventory(primaryBin.labelAdresse);

                    primaryBin.binContents = new List<BinContent>(primaryBin.inventoryItem._BinContent);

                    List<String> StockIds = new List<string>();
                    foreach (var bincontent in primaryBin.binContents)
                    {
                        StockIds.Add(bincontent.StockId);
                    }

                    primaryBin.productsinBinContent = new List<InventoryProduct>(await Common.GetInventoryProducts(new ProductSearchFilter { StockId = StockIds.ToArray() }));

                    primaryBin.productsinBinContent.Sort(delegate (InventoryProduct t1, InventoryProduct t2) { return (t1.ProductName.CompareTo(t2.ProductName)); });

                    foreach (var product in primaryBin.productsinBinContent)
                    {
                        var bincontent = primaryBin.binContents.Find(s => s.StockId == product.StockId);
                        var _item = new ListItem() { Name = product.ProductName, Id = bincontent.Id.ToString(), Quantity = bincontent.Quantity, BookedQuantity = bincontent.BookedQuantity, EAN = product.Ean, CodeSupplier = product.MainSupplier, showTransferButton = primaryBin.showTransferButton, showDeleteButton = primaryBin.showDeleteButton};
                        primaryBin.Items.Add(_item);
                    }
                }
        }

So far so good. It call the finction, save the result, and fill the list to display depending on the content.

Here's the constructor for the viewmodel public Inv2ViewModel

(int typePage, ListView primaryList, ListView secondaryList, BoxView selectBinBoxView, string title = "Move Goods")
        {
            Title = title;
            IsPrimaryBin = true;
            primaryBin = new BinDefinition(1,typePage);
            secondaryBin = new BinDefinition(2, typePage);
            primaryBin.Items = new ObservableCollection<ListItem>();
            secondaryBin.Items = new ObservableCollection<ListItem>();
            LoadItemsCommand = new Command(async () => Task.WaitAll(ExecuteLoadItemsCommand()));
            SwitchBinCommand = new Command(async () => await ExecuteSwitchBinCommand());
            this.primaryList = primaryList;
            this.secondaryList = secondaryList;
            this.selectBinBoxView = selectBinBoxView;
            pageType = typePage;
            isInit = true;

            secondaryList.TranslateTo(DeviceDisplay.MainDisplayInfo.Width, 0, 1000);
            LoadItemsCommand.Execute(true);
        }

My program was getting stuck in GetTaskInventory, right after the "finally", never getting out of the await until I put the .ConfigureAwait(false). Then it got out, but it now locks after the return. I do not understand what is going out. These functions are used quite often an never caused an issue.

Thank you for your help.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Here's your problem:

LoadItemsCommand = new Command(async () => Task.WaitAll(ExecuteLoadItemsCommand()));

You shouldn't block on asynchronous code; that can cause deadlocks. In this case, the code is using Task.WaitAll to block, and that causes the same deadlock as the more common .Result/.Wait() style of blocking.

First, I'd recommend using await just to fix this issue:

LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());

And then I'd recommend using alternative patterns for asynchronous data loading.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...