2017-10-07 16 views
0

UWPでテキストファイルを開き、すぐにそのコードに簡単なテキストを追加する簡単な練習コードを作成したかったのです。FileOpenPicker用のUWPで非同期メソッドを待機するにはどうすればよいですか?

public MainPage() 
{ 
    this.InitializeComponent(); 

    OpenFile(); 
    SaveFile(); 
} 

public async void OpenFile() 
{ 
    FileOpenPicker picker = new FileOpenPicker(); 
    picker.SuggestedStartLocation = PickerLocationId.Desktop; 
    picker.FileTypeFilter.Add(".txt"); 

    DataFile = await picker.PickSingleFileAsync(); 
    if (DataFile == null) { return; } 
} 

public async void SaveFile() 
{ 
    await FileIO.AppendTextAsync(DataFile, "" + DateTime.Now + "\n"); 
} 

private StorageFile DataFile { get; set; } 

期待セーブファイル()は直ちにのOpenFile(後に実行されるため、このコードは、セーブファイル()メソッドであるためエラーを返したように)とのOpenFileので()は(SAVEFILEためのターゲット・ファイルを検索する動作を完了していません)を使用します。事は、私がのOpenFileに次のコードを変更しようとすると、私はAggregateExceptionエラーを受け取り、次のとおりです。

DataFile = picker.PickSingleFileAsync(); 
Task task = Task.Run(async() => DataFile = await picker.PickSingleFileAsync()); 
task.Wait(); 
私はそれはセーブファイルの前に、対象のファイルを取得完了するまで、私は(のOpenFile()をブロックすることができますどのように思っていた

)が実行されます。

+0

これは、この質問の答えによって解決できます:https://stackoverflow.com/questions/32084943/async-lock-not-allowed – Laith

+0

非同期で構成されている、それはすべての方法をダウンカラスとここでのコアの問題ですそれは最後のカメであり、コンストラクタは非同期ではありません。これを逆にする必要があります。*最初にファイル名を要求し、*次に*クラスオブジェクトを作成します。その名前がMainPageであることは素晴らしいことではありません。UIを表示する前に、プログラムの開始時にすぐにユーザーの入力を求めないでください。ダイアログはウィンドウの上部に留まる必要があります。そうでなければ、プログラムには一般にファイル>開くコマンドがあるのです。 –

答えて

2

クラスのコンストラクタは高速であり、確かにの非同期メソッドを持つべきではありません。あなたのケースでは、防火忘れのような方法を実行している場合、ファイルを選択せず​​に保存しようとする競合状態があります。それから何も良いことはありません。

代わりに、あなたのメインページが作成されるとsoemthingを行うには、ユーザーが必要な場合は、例えば、このためにLoadedイベントを使用することがあります。また、私はタスクにあなたの方法を変更したことを

public MainPage() 
{ 
    this.InitializeComponent(); 
    this.Loaded += LoadedHandler; 
} 

private async void LoadedHandler(object sender, RoutedEventArgs e) 
{ 
    // assume that we want to do this only once 
    this.Loaded -= LoadedHandler; 
    await OpenFile(); 
    await SaveFile(); 
} 

public async Task OpenFile() 
{ 
    FileOpenPicker picker = new FileOpenPicker(); 
    picker.SuggestedStartLocation = PickerLocationId.Desktop; 
    picker.FileTypeFilter.Add(".txt"); 

    DataFile = await picker.PickSingleFileAsync(); 
    if (DataFile == null) { return; } 
} 

public async Task SaveFile() 
{ 
    await FileIO.AppendTextAsync(DataFile, "" + DateTime.Now + "\n"); 
} 

private StorageFile DataFile { get; set; } 

注 - avoid async voidです。

+1

それらを 'Task'に変換することはそれ自身では役に立ちません。あなたは' try/catch'の中に呼び出しを持たず、呼び出し元(イベントハンドラ)は 'void'です。例外は' 「観察されない」例外。 –

+0

@ PeterTorr-MSFTこの場合、あなたはそうです。編集後に提供されたリンクは、読者に何らかの光を与えるはずです。考えられる問題について言及するためにこれを追加しました。 – Romasz

関連する問題