2

ボタン クリック イベントを実行し、開いている間にテキスト ファイルを書き込むと、UI スレッドがまだハングしている理由は何ですか。書き終わるまで何もできません。

private async void WriteFileClick(object sender, RoutedEventArgs e)
    {
        string fileName = @"asyn3cfile.txt";
        string text = "Hello async, this was written while you were doing something else in the UI";

        StorageFolder storageFolder = KnownFolders.DocumentsLibrary;
        var writtenFile = await storageFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);

        using (IRandomAccessStream randomAccessStream = await writtenFile.OpenAsync(FileAccessMode.ReadWrite))
        {
            Stream stream = randomAccessStream.AsStreamForWrite();
            stream.Seek(0, SeekOrigin.Begin);
            WriteFileTextAsync(text, stream);
            await stream.FlushAsync();
            await randomAccessStream.FlushAsync();
        }
        Debug.WriteLine("{0} was created", fileName);
    }

    private async static void WriteFileTextAsync(string text, Stream stream)
    {
        for (int i = 0; i < 100; i++)
        {
            var fileText = string.Format("{0} in process {1}\n", text, i);
            byte[] textBytes = Encoding.UTF8.GetBytes(fileText);
            stream.SetLength(stream.Length + textBytes.Length);

            await stream.WriteAsync(textBytes, 0, textBytes.Length);
            new System.Threading.ManualResetEvent(false).WaitOne(100);
        }
    }

XAML

<Button x:Name="WriteFileInDocumentsButton" Content="Write a text file" Click="WriteFileClick"/>

理由はありますか?

4

2 に答える 2

3

変更する必要があります:

 private async static void WriteFileTextAsync(string text, Stream stream)
{
    for (int i = 0; i < 100; i++)
    {
        var fileText = string.Format("{0} in process {1}\n", text, i);
        byte[] textBytes = Encoding.UTF8.GetBytes(fileText);
        stream.SetLength(stream.Length + textBytes.Length);

        await stream.WriteAsync(textBytes, 0, textBytes.Length);
        new System.Threading.ManualResetEvent(false).WaitOne(100);
    }
}

 private async static Task GetFileTextAsync(string text, Stream stream)
{
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 100; i++)
    {
        sb.AppendLine(string.Format("{0} in process {1}\n", text, i));            
    }
    await stream.WriteAsync(textBytes, 0, textBytes.Length);
}

これはオーバーヘッドをいくらか節約するのに役立ちますが、さらに重要なことは、以下を変更する必要があることです:

 using (IRandomAccessStream randomAccessStream = await writtenFile.OpenAsync(FileAccessMode.ReadWrite))
    {
        Stream stream = randomAccessStream.AsStreamForWrite();
        stream.Seek(0, SeekOrigin.Begin);
        WriteFileTextAsync(text, stream);
        await stream.FlushAsync();
        await randomAccessStream.FlushAsync();
    }
    Debug.WriteLine("{0} was created", fileName);

WriteFileAysnc メソッドの呼び出しに await キーワードを含めます。

using (IRandomAccessStream randomAccessStream = await writtenFile.OpenAsync(FileAccessMode.ReadWrite))
    {
        Stream stream = randomAccessStream.AsStreamForWrite();
        stream.Seek(0, SeekOrigin.Begin);
        **await** WriteFileTextAsync(text, stream);
        await stream.FlushAsync();
        await randomAccessStream.FlushAsync();
    }
    Debug.WriteLine("{0} was created", fileName);
于 2012-12-24T14:42:47.367 に答える
1

記述コードにいくつかのバグがあります。WriteAsync を待っていません。WriteFileTextAsync はタスクを返し、待機する必要があります。

文字列を書くだけの場合は、FileIOヘルパー メソッドを使用する方が簡単です。

于 2012-12-23T19:02:50.473 に答える