异步读取 Excel 个工作表
Read Excel Worksheets Asynchronously
我正在尝试异步读取给定工作簿的所有 Excel 作品sheet,但不知何故它没有发生。这个想法是对每个 Excel sheet 中的前 123 个单元格求和并在最后打印它。代码编译 运行s 没有错误,但它没有读取所有工作 sheets,它只是跳过那部分,因为 async
.
namespace SyncAndAsync
{
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;
class Startup
{
static void Main()
{
string filePath = @"C:\Users\Desktop\Sample.xlsx";
Excel.Application excel = new Excel.Application();
excel.Visible = true;
excel.EnableAnimations = false;
Excel.Workbook wkb = Open(excel, filePath);
var calculation = CalculateAllWorksheetsAsync(wkb);
//foreach (var item in calculation)
//{
// Console.WriteLine(item);
//}
excel.EnableAnimations = true;
wkb.Close(true);
excel.Quit();
}
static async Task<List<Information>> CalculateAllWorksheetsAsync(Excel.Workbook wkb)
{
List<Task<Information>> tasks = new List<Task<Information>>();
foreach (Excel.Worksheet wks in wkb.Worksheets)
{
Task.Run(() => CalculateSingleWorksheetAsync(wks));
}
var results = await Task.WhenAll(tasks);
return new List<Information>(results);
}
static async Task<Information> CalculateSingleWorksheetAsync(Excel.Worksheet wks)
{
Information output = new Information();
int result = 0;
await Task.Run(() =>
{
for (int i = 1; i <= 123; i++)
{
result += (int)(wks.Cells[i, 1].Value);
}
});
output.WorksheetName = wks.Name;
output.WorksheetSum = result;
Console.WriteLine($"{wks.Name} - {result}");
return output;
}
static Excel.Workbook Open(Excel.Application excelInstance,
string fileName, bool readOnly = false,
bool editable = true, bool updateLinks = true)
{
Excel.Workbook book = excelInstance.Workbooks.Open(
fileName, updateLinks, readOnly,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, editable, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
return book;
}
}
}
添加了Information
class来使用任务,可能可以跳过:
namespace SyncAndAsync
{
class Information
{
public string WorksheetName { get; set; } = "";
public int WorksheetSum { get; set; } = 0;
}
}
依赖关系:
- 应添加引用
Microsoft.Office.Interop.Excel
;
- 将
string filePath = @"C:\Users\Desktop\Sample.xlsx";
更改为相关内容并确保在 Excel 文件中每个 sheet 的第一列中都有一些数字以获得结果;
问题 - 如何实现异步运行并显示所有工作sheet的总和?
有几个问题。首先,任务列表永远不会被填充,因此 WhenAll
调用不会执行任何操作。其次,主函数从不等待CalculateAllWorksheetsAsync
的结果。我对您的代码做了一些修改,见下文:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;
namespace ExcelTest {
public class Information {
public Information(string name, int sum) {
Name = name;
Sum = sum;
}
public string Name { get; set; }
public int Sum { get; set; }
}
class Program {
static void Main(){
MainAsync().GetAwaiter().GetResult();
}
private static async Task MainAsync() {
const string filePath = @"D:\file.xlsx";
var excel = new Excel.Application {Visible = true, EnableAnimations = false};
var wkb = Open(excel, filePath);
var calculation = await CalculateAllWorksheetsAsync(wkb);
foreach (var item in calculation) {
Console.WriteLine($"{item.Name} - {item.Sum}");
}
excel.EnableAnimations = true;
wkb.Close(true);
excel.Quit();
Console.Read();
}
private static async Task<List<Information>> CalculateAllWorksheetsAsync(Excel.Workbook wkb) {
var tasks = wkb.Worksheets.Cast<Excel.Worksheet>().Select(CalculateSingleWorksheetAsync);
var results = await Task.WhenAll(tasks);
return results.ToList();
}
private static async Task<Information> CalculateSingleWorksheetAsync(Excel.Worksheet wks) {
int result = await Task.Run(() =>
Enumerable.Range(1, 123).Sum(index => (int) (wks.Cells[index, 1].Value2)));
Console.WriteLine($"{wks.Name} - {result}");
return new Information(wks.Name, result);
}
private static Excel.Workbook Open(Excel.Application excelInstance,
string fileName, bool readOnly = false,
bool editable = true, bool updateLinks = true) {
return excelInstance.Workbooks.Open(
fileName, updateLinks, readOnly,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, editable, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
}
}
}
示例输出:
我正在尝试异步读取给定工作簿的所有 Excel 作品sheet,但不知何故它没有发生。这个想法是对每个 Excel sheet 中的前 123 个单元格求和并在最后打印它。代码编译 运行s 没有错误,但它没有读取所有工作 sheets,它只是跳过那部分,因为 async
.
namespace SyncAndAsync
{
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;
class Startup
{
static void Main()
{
string filePath = @"C:\Users\Desktop\Sample.xlsx";
Excel.Application excel = new Excel.Application();
excel.Visible = true;
excel.EnableAnimations = false;
Excel.Workbook wkb = Open(excel, filePath);
var calculation = CalculateAllWorksheetsAsync(wkb);
//foreach (var item in calculation)
//{
// Console.WriteLine(item);
//}
excel.EnableAnimations = true;
wkb.Close(true);
excel.Quit();
}
static async Task<List<Information>> CalculateAllWorksheetsAsync(Excel.Workbook wkb)
{
List<Task<Information>> tasks = new List<Task<Information>>();
foreach (Excel.Worksheet wks in wkb.Worksheets)
{
Task.Run(() => CalculateSingleWorksheetAsync(wks));
}
var results = await Task.WhenAll(tasks);
return new List<Information>(results);
}
static async Task<Information> CalculateSingleWorksheetAsync(Excel.Worksheet wks)
{
Information output = new Information();
int result = 0;
await Task.Run(() =>
{
for (int i = 1; i <= 123; i++)
{
result += (int)(wks.Cells[i, 1].Value);
}
});
output.WorksheetName = wks.Name;
output.WorksheetSum = result;
Console.WriteLine($"{wks.Name} - {result}");
return output;
}
static Excel.Workbook Open(Excel.Application excelInstance,
string fileName, bool readOnly = false,
bool editable = true, bool updateLinks = true)
{
Excel.Workbook book = excelInstance.Workbooks.Open(
fileName, updateLinks, readOnly,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, editable, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
return book;
}
}
}
添加了Information
class来使用任务,可能可以跳过:
namespace SyncAndAsync
{
class Information
{
public string WorksheetName { get; set; } = "";
public int WorksheetSum { get; set; } = 0;
}
}
依赖关系:
- 应添加引用
Microsoft.Office.Interop.Excel
; - 将
string filePath = @"C:\Users\Desktop\Sample.xlsx";
更改为相关内容并确保在 Excel 文件中每个 sheet 的第一列中都有一些数字以获得结果;
问题 - 如何实现异步运行并显示所有工作sheet的总和?
有几个问题。首先,任务列表永远不会被填充,因此 WhenAll
调用不会执行任何操作。其次,主函数从不等待CalculateAllWorksheetsAsync
的结果。我对您的代码做了一些修改,见下文:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;
namespace ExcelTest {
public class Information {
public Information(string name, int sum) {
Name = name;
Sum = sum;
}
public string Name { get; set; }
public int Sum { get; set; }
}
class Program {
static void Main(){
MainAsync().GetAwaiter().GetResult();
}
private static async Task MainAsync() {
const string filePath = @"D:\file.xlsx";
var excel = new Excel.Application {Visible = true, EnableAnimations = false};
var wkb = Open(excel, filePath);
var calculation = await CalculateAllWorksheetsAsync(wkb);
foreach (var item in calculation) {
Console.WriteLine($"{item.Name} - {item.Sum}");
}
excel.EnableAnimations = true;
wkb.Close(true);
excel.Quit();
Console.Read();
}
private static async Task<List<Information>> CalculateAllWorksheetsAsync(Excel.Workbook wkb) {
var tasks = wkb.Worksheets.Cast<Excel.Worksheet>().Select(CalculateSingleWorksheetAsync);
var results = await Task.WhenAll(tasks);
return results.ToList();
}
private static async Task<Information> CalculateSingleWorksheetAsync(Excel.Worksheet wks) {
int result = await Task.Run(() =>
Enumerable.Range(1, 123).Sum(index => (int) (wks.Cells[index, 1].Value2)));
Console.WriteLine($"{wks.Name} - {result}");
return new Information(wks.Name, result);
}
private static Excel.Workbook Open(Excel.Application excelInstance,
string fileName, bool readOnly = false,
bool editable = true, bool updateLinks = true) {
return excelInstance.Workbooks.Open(
fileName, updateLinks, readOnly,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, editable, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
}
}
}
示例输出: