如何正确使用 FileStream.ReadAsync 不阻塞 UI
How to use FileStream.ReadAsync properly to not blocking UI
我是异步编程的新手。
我的 UI 中有一个按钮和文本框。我想单击该按钮,它将使用 FileStream.ReadAsync 方法读取文件,然后它应该在文本框中显示文件的结果。
问题是我不想在读取文件时阻塞我的 UI。
我认为使用 Read 方法应该这样做。但它不起作用。此方法有何不正确之处以及如何将 Read 更改为 ReadAsync?
private void Button_Click(object sender, RoutedEventArgs e)
{
string filename = @"D:\Log\log.txt";
byte[] result;
UnicodeEncoding uniencoding = new UnicodeEncoding();
using (FileStream SourceStream = File.Open(filename, FileMode.Open))
{
result = new byte[SourceStream.Length];
Task<int> tf = new Task<int>(()=> SourceStream.Read(result, 0, (int)SourceStream.Length));
tf.ContinueWith((x) =>
{
try
{
string txt = Encoding.ASCII.GetString(result);
Dispatcher.BeginInvoke((Action)(() => txtBox.Text = txt));
}
catch (Exception ae)
{
MessageBox.Show(ae.Message);
}
});
tf.Start();
}
如果我的理解正确并且您只是以 ASCII 编码读取文本文件并将内容放入文本框中,那么您最好使用 File.ReadAllTextAsync()
,它在 . NET 核心:
private async void Button_Click(object sender, RoutedEventArgs e)
{
string filename = @"D:\Log\log.txt";
try
{
txtBox.Text = await File.ReadAllTextAsync(filename, Encoding.ASCII);
}
catch (Exception ae)
{
MessageBox.Show(ae.Message);
}
}
异步读取文件其实有点奇怪。有时即使你使用异步方法读取它实际上也不会异步发生。例如,FileStream
constructors has a useAsync
parameter, and another constructor has an options
parameter where you can specify FileOptions.Asychronous
. But File.Open()
doesn't use either of those constructors, which means that the file access doesn't end up being asynchronous, even if you use ReadAsync()
. File.ReadAllTestAsync()
does.
之一
但即便如此,this issue 也讨论了 打开 文件的行为实际上并不是异步发生的,即使 reading 确实如此,如果您正在访问远程文件系统,这可能是一个问题。因此,如果您对锁定 UI 的代码有疑问,请将 await
行更改为:
txtBox.Text = await Task.Run(() => File.ReadAllTextAsync(filename, Encoding.ASCII));
这将 运行 ReadAllTextAsync
在另一个线程上。 Task.Run
是最好的方法。几乎没有理由使用 new Task()
.
我是异步编程的新手。 我的 UI 中有一个按钮和文本框。我想单击该按钮,它将使用 FileStream.ReadAsync 方法读取文件,然后它应该在文本框中显示文件的结果。 问题是我不想在读取文件时阻塞我的 UI。 我认为使用 Read 方法应该这样做。但它不起作用。此方法有何不正确之处以及如何将 Read 更改为 ReadAsync?
private void Button_Click(object sender, RoutedEventArgs e)
{
string filename = @"D:\Log\log.txt";
byte[] result;
UnicodeEncoding uniencoding = new UnicodeEncoding();
using (FileStream SourceStream = File.Open(filename, FileMode.Open))
{
result = new byte[SourceStream.Length];
Task<int> tf = new Task<int>(()=> SourceStream.Read(result, 0, (int)SourceStream.Length));
tf.ContinueWith((x) =>
{
try
{
string txt = Encoding.ASCII.GetString(result);
Dispatcher.BeginInvoke((Action)(() => txtBox.Text = txt));
}
catch (Exception ae)
{
MessageBox.Show(ae.Message);
}
});
tf.Start();
}
如果我的理解正确并且您只是以 ASCII 编码读取文本文件并将内容放入文本框中,那么您最好使用 File.ReadAllTextAsync()
,它在 . NET 核心:
private async void Button_Click(object sender, RoutedEventArgs e)
{
string filename = @"D:\Log\log.txt";
try
{
txtBox.Text = await File.ReadAllTextAsync(filename, Encoding.ASCII);
}
catch (Exception ae)
{
MessageBox.Show(ae.Message);
}
}
异步读取文件其实有点奇怪。有时即使你使用异步方法读取它实际上也不会异步发生。例如,FileStream
constructors has a useAsync
parameter, and another constructor has an options
parameter where you can specify FileOptions.Asychronous
. But File.Open()
doesn't use either of those constructors, which means that the file access doesn't end up being asynchronous, even if you use ReadAsync()
. File.ReadAllTestAsync()
does.
但即便如此,this issue 也讨论了 打开 文件的行为实际上并不是异步发生的,即使 reading 确实如此,如果您正在访问远程文件系统,这可能是一个问题。因此,如果您对锁定 UI 的代码有疑问,请将 await
行更改为:
txtBox.Text = await Task.Run(() => File.ReadAllTextAsync(filename, Encoding.ASCII));
这将 运行 ReadAllTextAsync
在另一个线程上。 Task.Run
是最好的方法。几乎没有理由使用 new Task()
.