这里我需要将一些数据从本地服务器导出到Excel中。我正在使用async
调用该方法。但是,它仍然在导出数据时阻止了用户界面。
我可能知道UI被阻止的原因吗?
另外,我需要一些澄清
1)
await
关键字用于等待一段时间,直到该过程为止 完成,然后差异b / w同步和 异步过程。2)如果一个方法被声明为
Async
任务,那么所有内部方法 表现为异步?3)执行内部方法(method1,method2,method3)时,method3将执行 取决于方法1。因此,为method1添加
await
关键字。我 正确?
代码段:
private async void ConvertExcel(object sender)
{
var excelEngine = new ExcelEngine();
var application = excelEngine.Excel;
var newbookWorkbook = application.Workbooks.Create(1);
var work = newbookWorkbook.Worksheets[0];
var openDialog = new SaveFileDialog
{
FilterIndex = 2,
Filter = "Excel 97 to 2003 Files(*.xls)|*.xls|Excel 2007 to 2013 Files(*.xlsx)|*.xlsx"
};
if (openDialog.ShowDialog() == true)
{
newbookWorkbook.Version = openDialog.FilterIndex == 1 ? ExcelVersion.Excel97to2003 : ExcelVersion.Excel2013;
}
else
return;
try
{
// This method is used to get the data from server.
var table = GetFullDataAsync();
work.ImportDataTable(table, true, 1, 1, true);
using (Stream stream = openDialog.OpenFile())
{
newbookWorkbook.SaveAs(stream);
}
newbookWorkbook.Close();
excelEngine.Dispose();
}
catch (Exception exception)
{
Console.WriteLine("Exception message: {0}",ex.Message);
}
}
internal async Task<DataTable> GetFullDataAsync()
{
DataTable dataTable = new DataTable();
dataTable = GetDataFromServer(DataEngine.Query,DataEngine.Connection);
dataTable.Locale = CultureInfo.InvariantCulture;
return dataTable;
}
public DataTable GetDataFromServer(string query, DbConnection connection)
{
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
var command = connection.CreateCommand();
command.CommandText = query;
command.Connection = connection;
var reader = command.ExecuteReader();
var dataTable = new DataTable
{
Locale = System.Globalization.CultureInfo.InvariantCulture
};
dataTable.Load(reader);
return dataTable;
}
答案 0 :(得分:2)
1)await关键字用于等待一段时间直到进程完成,然后b / w同步和异步进程有什么区别。
同步:等待阻塞线程,所以锁定ui
异步:等待释放线程,因此不会阻止ui
2)如果一个方法被声明为异步任务,那么所有内部方法都以异步方式执行?
不要认为这是真的。您可能希望情况如此,但作为开发人员,您可以通过这种方式对其进行编码 编译器不会为您强制执行此操作。
在上面的代码中,答案是否定的;你的代码不是异步的。请注意,您从不使用await
关键字
您可能需要首先以异步方式访问数据(返回任务),否则async / await关键字无法帮助您。
3)执行内部方法(method1,method2,method3)时,method3将取决于method1。因此,为method1设置await关键字。我是对的吗?
是。如果每个方法都返回一个Task,那么等待它们全部。 通常当你在一个地方开始使用await时,它会在你的其余代码中冒出来,所以你不断添加更多的东西等等。
答案 1 :(得分:0)
你试过吗
GetFullDataAsync().ContinueWith((table)=>{
work.ImportDataTable(table, true, 1, 1, true);
using (Stream stream = openDialog.OpenFile())
{
newbookWorkbook.SaveAs(stream);
}
newbookWorkbook.Close();
excelEngine.Dispose();
})
答案 2 :(得分:0)
您可以更改代码以使用与Sql server的异步通信:
private async Task ConvertExcel(object sender)
{
var excelEngine = new ExcelEngine();
var application = excelEngine.Excel;
var newbookWorkbook = application.Workbooks.Create(1);
var work = newbookWorkbook.Worksheets[0];
var openDialog = new SaveFileDialog
{
FilterIndex = 2,
Filter = "Excel 97 to 2003 Files(*.xls)|*.xls|Excel 2007 to 2013 Files(*.xlsx)|*.xlsx"
};
if (openDialog.ShowDialog() == true)
{
newbookWorkbook.Version = openDialog.FilterIndex == 1 ? ExcelVersion.Excel97to2003 : ExcelVersion.Excel2013;
}
else
return;
try
{
// This method is used to get the data from server.
var table = await GetFullDataAsync();
work.ImportDataTable(table, true, 1, 1, true);
var saveWorkbookTask = Task.Run(() => {
using (Stream stream = openDialog.OpenFile())
{
newbookWorkbook.SaveAs(stream);
}
});
await saveWorkbookTask;
newbookWorkbook.Close();
excelEngine.Dispose();
}
catch (Exception exception)
{
Console.WriteLine("Exception message: {0}",ex.Message);
}
}
internal async Task<DataTable> GetFullDataAsync()
{
DataTable dataTable = new DataTable();
dataTable = await GetDataFromServer(DataEngine.Query,DataEngine.Connection);
dataTable.Locale = CultureInfo.InvariantCulture;
return dataTable;
}
public async Task<DataTable> GetDataFromServer(string query, DbConnection connection)
{
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
var command = connection.CreateCommand();
command.CommandText = query;
command.Connection = connection;
var reader = await command.ExecuteReaderAsync();
var loadTableTask = Task.Run(() => {
var dataTable = new DataTable
{
Locale = System.Globalization.CultureInfo.InvariantCulture
};
dataTable.Load(reader);
return dataTable;
});
return await loadTableTask;
}
但是你仍然有阻止IO操作。因此,如果您的文件很大,则在将文件写入磁盘时将阻止UI。