Цепочка задач ASYNC внутри задач в приложении cmd вызывает сбой без исключения - PullRequest
0 голосов
/ 30 апреля 2019

Редактировать: вот мой основной метод

static void Main(string[] args)
{
    LogNewOrders();
    DataTable initialData = ControllerSqlAgent.SelectQuery(Resources.Controller, Resources.qryGetInitalData);
    Console.WriteLine($"|There are {initialData.Rows.Count} orders to check|");
    Task.WhenAll(UpdateItemCountsField(initialData));
}

У меня есть метод с именем UpdateItemCountsField(datatable)

Цель этого метода - получить оба:

  • всего отменено
  • всего отправлено

    private static async Task UpdateItemCountsField(DataTable initialData)
    {
        try
        {
            foreach (DataRow row in initialData.Rows)
            {
                string narvarId = row["NarvarID"].ToString();
                int orderedItemCount = (int)row["ItemsOrdered"];
                int totalShippedItems = (int)row["ItemsShipped"]; ;
                int totalCancelledItems = (int)row["ItemsCancelled"];
                string locateConstraint = GetLocateInConstraint(row["OrderNumber"].ToString(), row["CompanyNumber"].ToString());
                Task<int> totalShippedItemsTask = CheckShipmentCountsAsync(locateConstraint, row["OrderNumber"].ToString(), row["CompanyNumber"].ToString(), totalShippedItems, narvarId);
                Task<int> totalCancelledItemsTask = CheckCancellationCountsAsync(locateConstraint, row["OrderNumber"].ToString(), row["CompanyNumber"].ToString(), totalCancelledItems, narvarId); ;
                int[] result = await Task.WhenAll(totalShippedItemsTask, totalCancelledItemsTask);
                //totalShippedItems = CheckShipmentCounts(locateConstraint, row["OrderNumber"].ToString(), row["CompanyNumber"].ToString(), totalShippedItems, narvarId);
                //totalCancelledItems = CheckCancellationCounts(locateConstraint, row["OrderNumber"].ToString(), row["CompanyNumber"].ToString(), totalCancelledItems, narvarId);
                Console.WriteLine($"|ID:{narvarId}|Ordered: {orderedItemCount}|Shipped: {result[0]}|Cancelled: {result[1]}|");
                Console.WriteLine("|___________________________________________|");
            }
        }
        catch
        {
            throw;
        }
    }
    

У меня есть два объекта Task, которые я получаю с помощью асинхронных методов:

Task<int> totalShippedItemsTask = CheckShipmentCountsAsync(params);
Task<int> totalCancelledItemsTask = CheckCancellationCountsAsync(params);

Затем я получаю свои результаты примерно так (именно здесь происходит сбой программы)

int[] result = await Task.WhenAll(totalShippedItemsTask,totalCancelledItemsTask);

в пределах CheckShipmentCoutnsAsync(params) и CheckCancellationCountsAsync(params) - это еще два Task<int> объекта.Это связано с тем, что есть два источника данных, которые мне нужно извлечь из

   private static async Task<int> CheckShipmentCountsAsync(string locateConstraint, string orderNumber, string companyNumber, int currentShippedItemCount, string narvarId)
    {
        Task<int> wmsShippedCountTask = WmsSqlAgent.GetCountOfShippedItemsAsync(orderNumber, companyNumber);
        Task<int> locateShippedCountTask = LocateSqlAgent.GetCountOfShippedItemsAsync(locateConstraint);
        int[] result = await Task.WhenAll(wmsShippedCountTask, locateShippedCountTask);
        int newShippedItemCount = result.Sum();
        if (newShippedItemCount > currentShippedItemCount)
            ControllerSqlAgent.UpdateShippedItemCount(narvarId, newShippedItemCount);
        return newShippedItemCount;
    }

Метод CheckCancelCountsAsync(PARAMS) такой же, как и выше, но для отмен.

Когда моя программа запускается,Он выполняет задание, а затем падает без каких-либо исключений и никогда не достигает следующего datarow для выполнения асинхронных методов.Я что-то здесь пропускаю?Почему мое приложение вылетает без исключения?причина, по которой я считаю, что это происходит сбой из-за того, что он никогда не попадает в Console.Writeline ();сразу после того, как я получил массив результатов из Task.WhenAll

А вот метод источника данных, который извлекает фактическое число

internal static async Task<int> GetCountOfCancelledItemsAsync(string orderNumber, string companyNumber)
{
    int itemCount = 0;
    await Task.Run(() =>
    {
        try
        {
            using (var connection = new SqlConnection(Resources.WMS))
            {
                connection.Open();

                using (var command = new SqlCommand(Resources.qryWmsGetCancelledItemCount, connection))
                {
                    command.Parameters.AddWithValue("@orderNumber", orderNumber);
                    command.Parameters.AddWithValue("@companyNumber", companyNumber);
                    itemCount = int.Parse(command.ExecuteScalar().ToString());
                }

                connection.Close();
            }
        }
        catch (SqlException E)
        {
            string message = E.Message;
            throw;
        }
        return itemCount;
    });
    return itemCount;

При просмотре кода я вижу, что моя программа падаеткогда я доберусь до nt[] result = await Task.WhenAll(totalShippedItemsTask, totalCancelledItemsTask);, но все равно не исключение.

1 Ответ

1 голос
/ 30 апреля 2019

Вы не ожидали результатов Task.WhenAll(UpdateItemCountsField(initialData)) в вашем основном методе. Это означает, что программа завершит работу, не дожидаясь завершения выполнения этого кода.

Измените свой метод на это:

static async Task Main(string[] args)
{
    LogNewOrders();
    DataTable initialData = ControllerSqlAgent.SelectQuery(Resources.Controller, Resources.qryGetInitalData);
    Console.WriteLine($"|There are {initialData.Rows.Count} orders to check|");
    await UpdateItemCountsField(initialData);
}

Так как UpdateItemCountsField возвращает одну задачу, Task.When при ее переносе был лишним, поэтому я удалил это из кода в своем ответе.

Обратите внимание, что вы должны использовать C # 7.1 или более позднюю версию, чтобы иметь асинхронный основной метод.

Убедитесь, что для любого метода, возвращающего задачу, вы await получили результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...