我是C#的新手。我正在尝试使用StorageFile类打开一对CSV文本文件,但是我需要在类构造函数(不能异步)中完成它:
private async Task SetupFileAccess()
{
MainCarDataStorageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///leaf.csv"));
var MainCarDataInputStream = await MainCarDataStorageFile.OpenReadAsync();
var MainCarDataClassicStream = MainCarDataInputStream.AsStreamForRead();
MainCarDataStream = new StreamReader(MainCarDataClassicStream);
await MainCarDataStream.ReadLineAsync(); //clear header line from csv
LookupTableStorageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Full_Charge_To_Empty.csv"));
var LookupTableInputStream = await LookupTableStorageFile.OpenReadAsync();
var LookupTableClassicStream = LookupTableInputStream.AsStreamForRead();
LookupTableDataStream = new StreamReader(LookupTableClassicStream);
await LookupTableDataStream.ReadLineAsync(); //clear header line from csv
}
然后我在该函数上调用Wait()
以阻止执行。
问题是当我到达第二个OpenReadAsync()函数调用以打开到第二个文件的流(Full_Charge_to_Empty.csv)时,该程序会永远搅动。没有崩溃,没有进展。
似乎我只能访问打开的第一个文件。如果我注释掉第一个文件访问(leaf.csv),则可以访问第二个文件。如果切换位置(leaf.csv已打开2号),则无法打开leaf.csv。
我感觉对于这些文件访问的工作方式肯定有些不了解...是因为我对第一个文件(leaf.csv)的访问正在占用某种类型的资源吗?感谢帮助!
答案 0 :(得分:0)
问题是您试图强制异步函数在构造函数中同步完成;这不会很好地结束。正确的方法是使用异步工厂方法来预先加载工作,然后返回填充的对象。例如:
<AlternatingItemTemplate>
<tr><td><%# Eval("DayName") %></td></tr>
</ItemTemplate>
使用它:
class Test
{
// Make constructor private so no-one can create it
private Test()
{ }
// Simple string properties that can't be async
public string Text1 { get; private set; }
public string Text2 { get; private set; }
// Async factory method that can do async things
public static async Task<Test> CreateAsync()
{
var result = new Test();
result.Text1 = await LoadFile("file1.txt");
result.Text2 = await LoadFile("file2.txt");
return result;
}
// Helper function
static async Task<string> LoadFile(string filename)
{
var file = await Package.Current.InstalledLocation.GetFileAsync(filename);
var size = (await file.GetBasicPropertiesAsync()).Size;
var reader = new DataReader(await file.OpenReadAsync());
reader.UnicodeEncoding = UnicodeEncoding.Utf8;
await reader.LoadAsync((uint)size);
// assumes single-byte UTF codepoints, eg ASCII
return reader.ReadString((uint)size);
}
}