【问题标题】:Task never reaching its end任务永远不会结束
【发布时间】:2021-01-11 13:20:01
【问题描述】:

我正在尝试运行一项任务,但它似乎永远不会到达终点,卡住了。我通常会怀疑无限循环,但这次没有循环。这段代码在安卓设备上运行,在 xamarin 表单下。

首先,这是最终锁定的任务。

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;
        }

很简单,它调用一个服务(服务正在工作)并得到一些结果。

其次,这是调用它的一部分(来自视图模型):

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);
                    }
                }
        }

到目前为止一切顺利。它调用函数,保存结果,并根据内容填充列表以显示。

这是视图模型的构造函数 公共 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);
        }

我的程序卡在 GetTaskInventory 中,就在“finally”之后,直到我放置 .ConfigureAwait(false) 才退出等待。然后它出来了,但现在它在返回后锁定。我不明白发生了什么。这些功能经常使用,从来没有引起过问题。

感谢您的帮助。

【问题讨论】:

  • 问题是以下方法没有返回:result = client.GetLineTaskInventory(labeladresse);

标签: c# android xamarin.forms task


【解决方案1】:

这是你的问题:

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

You shouldn't block on asynchronous code; that can cause deadlocks。在这种情况下,代码使用Task.WaitAll 进行阻塞,这会导致与更常见的.Result/.Wait() 阻塞样式相同的死锁。

首先,我建议使用await 来解决这个问题:

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

然后我建议使用alternative patterns for asynchronous data loading

【讨论】:

  • 它曾经是那里的代码,但我遇到了一个问题,因为程序没有等待任务完成。它只会开始任务,并在我试图获取尚未处理的信息时继续给我一个错误。使用 Tas.WaitAll 确保它正在等待它的结束。
  • @Elgate:更好的解决方案是(异步)等待数据加载,而不是阻塞加载方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-20
  • 2021-05-17
  • 2013-04-09
  • 2010-12-27
  • 2021-08-05
  • 2016-06-03
  • 2011-01-20
相关资源
最近更新 更多