[解決済み] 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
にはたくさんの単語があり、私はそれをs変数に読み込んでいます。
async
と
await
のキーワードは、C# 5では
Async CTP Library
を使用して、WPFアプリがハングアップしないようにします。今のところ、私は以下のコードを持っています。
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アプリのフリーズを防ぐために、同期ではなく非同期でファイルを読み込むことが目的です。
どんな助けでも感謝します、ありがとうございます
どのように解決するのですか?
アップデイト
: 非同期バージョンの
File.ReadAll[Lines|Bytes|Text]
,
File.AppendAll[Lines|Text]
と
File.WriteAll[Lines|Bytes|Text]
は、現在では
にマージされ、.NET Core
にマージされ、.NET Core 2.0 に同梱されました。また、.NET Standard 2.1 にも含まれています。
使用方法
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);
}
EDIT
: と同じコードを実現するための方法をいくつか紹介します。
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();
}
}
関連
-
[解決済み】プログラム実行中に1秒待つ
-
[解決済み】Visual Studio: 操作を完了できませんでした。パラメータが正しくありません
-
[解決済み] C#で文字列のエンコーディングを手動で指定せずに、一貫性のあるバイト表現を得るには?
-
[解決済み] forEachループでasync/awaitを使用する
-
[解決済み] DateTime型の誕生日から年齢を計算するにはどうしたらいいですか?
-
[解決済み] Microsoft Officeをインストールせずに、C#でExcel(.XLSおよび.XLSX)ファイルを作成するにはどうすればよいですか?
-
[解決済み] async」と「await」の使い方とタイミング
-
[解決済み] 非同期Task<T>メソッドを同期的に実行するにはどうしたらいいですか?
-
[解決済み] async/await関数を並列に呼び出す
-
[解決済み] 複数のタスクにasync/awaitを使用する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】エラー。「戻り値を変更できません」 C#
-
[解決済み】統合マネージドパイプラインモードで適用されないASP.NETの設定が検出された
-
[解決済み】「入力文字列が正しい形式ではありませんでした」エラーの解決方法は?[重複しています]。
-
[解決済み] DBNullから他の型にオブジェクトをキャストすることができない
-
[解決済み】WPFでXamlファイルにコメントを追加する方法は?
-
[解決済み】値が期待した範囲に収まらない
-
[解決済み】Moqを使用してメソッド呼び出しを検証する
-
[解決済み】ファイルへの読み書きの際に共有違反のIOExceptionが発生する C#
-
[解決済み] ...基礎となる接続は閉じられました。予期しないエラーが受信で発生しました
-
[解決済み】インデックスが範囲外でした。コレクションパラメータname:indexのサイズより小さく、非負でなければなりません。