Files.ReadAllLines를 비 동기화하고 결과를 찾는 방법은 무엇입니까?
다음 코드가 있습니다.
private void button1_Click(object sender, RoutedEventArgs e)
{
button1.IsEnabled = false;
var s = File.ReadAllLines("Words.txt").ToList(); // my WPF app hangs here
// do something with s
button1.IsEnabled = true;
}
Words.txt
내가들로 읽은 단어 변수가 너무 많아서 WPF 앱이 멈추지 않도록 C # 5에서 async
및 await
키워드를 사용하려고합니다 Async CTP Library
. 지금까지 다음 코드가 있습니다.
private async void button1_Click(object sender, RoutedEventArgs e)
{
button1.IsEnabled = false;
Task<string[]> ws = Task.Factory.FromAsync<string[]>(
// What do i have here? there are so many overloads
); // is this the right way to do?
var s = await File.ReadAllLines("Words.txt").ToList(); // what more do i do here apart from having the await keyword?
// do something with s
button1.IsEnabled = true;
}
목표는 WPF 앱이 중단되는 것을 방지하기 위해 동기화가 아닌 것으로 파일을 읽는 것입니다.
어떤 도움을 주시면 감사하겠습니다!
UPDATE : 최신 버전 , 그리고 지금은 한 .NET 코어에 통합 및 .NET 코어 2.0과 함께 제공됩니다. .NET Standard 2.1에도 포함되어 있습니다.File.ReadAll[Lines|Bytes|Text]
File.AppendAll[Lines|Text]
File.WriteAll[Lines|Bytes|Text]
사용 Task.Run
자체로의 래퍼 인 Task.Factory.StartNew
랩퍼 것은 코드 냄새입니다 .
차단 기능을 사용하여 CPU를 사용하지 않고 다음과 같이 진정한 의미의 IO 메소드를 기다려야합니다 .StreamReader.ReadToEndAsync
using (var reader = File.OpenText("Words.txt"))
{
var fileText = await reader.ReadToEndAsync();
// Do something with fileText...
}
이것은 전체 파일을 얻는 string
대신의 List<string>
. 대신 줄이 필요하면 다음과 같이 나중에 쉽게 쉽게 분할 할 수 있습니다.
using (var reader = File.OpenText("Words.txt"))
{
var fileText = await reader.ReadToEndAsync();
return fileText.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
}
편집 : 다음은 과 동일한 코드를 달성하는 몇 가지 방법 File.ReadAllLines
이지만 진정한 의미 방식입니다. 코드는 자체 구현을 기반으로합니다 .File.ReadAllLines
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
public static class FileEx
{
/// <summary>
/// This is the same default buffer size as
/// <see cref="StreamReader"/> and <see cref="FileStream"/>.
/// </summary>
private const int DefaultBufferSize = 4096;
/// <summary>
/// Indicates that
/// 1. The file is to be used for asynchronous reading.
/// 2. The file is to be accessed sequentially from beginning to end.
/// </summary>
private const FileOptions DefaultOptions = FileOptions.Asynchronous | FileOptions.SequentialScan;
public static Task<string[]> ReadAllLinesAsync(string path)
{
return ReadAllLinesAsync(path, Encoding.UTF8);
}
public static async Task<string[]> ReadAllLinesAsync(string path, Encoding encoding)
{
var lines = new List<string>();
// Open the FileStream with the same FileMode, FileAccess
// and FileShare as a call to File.OpenText would've done.
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultBufferSize, DefaultOptions))
using (var reader = new StreamReader(stream, encoding))
{
string line;
while ((line = await reader.ReadLineAsync()) != null)
{
lines.Add(line);
}
}
return lines.ToArray();
}
}
파일의 읽기를 위해 Stream.ReadAsync를 사용합니다.
private async void Button_Click(object sender, RoutedEventArgs e)
{
string filename = @"c:\Temp\userinputlog.txt";
byte[] result;
using (FileStream SourceStream = File.Open(filename, FileMode.Open))
{
result = new byte[SourceStream.Length];
await SourceStream.ReadAsync(result, 0, (int)SourceStream.Length);
}
UserInput.Text = System.Text.Encoding.ASCII.GetString(result);
}
귀하의 질문에 설명 된 문제도 발생했습니다. 이전 답변에서 간단하게 해결했습니다.
string[] values;
StorageFolder folder = ApplicationData.Current.LocalFolder; // Put your location here.
IList<string> lines = await FileIO.ReadLinesAsync(await folder.GetFileAsync("Words.txt"););
lines.CopyTo(values, 0);
이 시도 :
private async void button1_Click(object sender, RoutedEventArgs e)
{
button1.IsEnabled = false;
try
{
var s = await Task.Run(() => File.ReadAllLines("Words.txt").ToList());
// do something with s
}
finally
{
button1.IsEnabled = true;
}
}
편집하다 :
이것이 작동하기 위해 try-finally가 필요하지 않습니다. 실제로 변경해야하는 단 한 줄입니다. 작동 방식을 설명하려면 : 이것은 다른 스레드를 생성하고 (실제로 스레드 풀에서 하나를 가져옴) 해당 스레드가 파일을 읽도록합니다. 파일 읽기가 끝나면 button1_Click 메서드의 나머지 부분이 결과와 함께 (GUI 스레드에서) 호출됩니다. 이것은 아마도 가장 효율적인 솔루션은 아니지만 GUI를 차단하지 않는 가장 간단한 코드 변경 일 것입니다.
참고 URL : https://stackoverflow.com/questions/13167934/how-to-async-files-readalllines-and-await-for-results
'ProgramingTip' 카테고리의 다른 글
생성자에서 setter 호출 (0) | 2020.12.04 |
---|---|
console.log () 호출을 Jasmine 테스트의 표준 출력으로 리디렉션 (0) | 2020.12.04 |
활성 탭을 사용하는 모든 탭을 닫으시겠습니까? (0) | 2020.12.04 |
정의되지 않은 동작 밖에서 전역 배열에 액세스하고 동작합니까? (0) | 2020.12.04 |
Android Studio 키보드 단축키 제어 (0) | 2020.12.03 |