编辑: 这是我的主要方法
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)
与上述方法相同,但要取消。
我的程序运行时,它命中任务,然后崩溃而没有任何异常,并且永远不会到达下一个数据行以执行异步方法。我在这里想念一块吗?为什么我的应用程序毫无例外地崩溃。我之所以认为它崩溃是因为它从未进入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);
时程序崩溃,但仍然没有例外。
答案 0 :(得分:1)
您尚未在主要方法中等待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,因此Task.WhenAll包装它是多余的,所以我从答案中的代码中删除了它。
请注意,您must be using C# 7.1或更高版本才能使用异步main方法。
确保在返回Task的任何方法中,您await
的结果。