简体   繁体   中英

Async when writing File in Windows 8

Any reason why when I execute a button click event and writing a text file while it's open it is still hanging the UI thread. Can't do anything until the writing finishes.

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"/>

Any reasons?

You should change:

 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);
    }
}

to

 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);
}

this will help save some overhead, but then more importantly you must change:

 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);

to include the await keyword on the WriteFileAysnc Method Invocation.

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);

There are some bugs in your writing code. You are not awaiting the WriteAsync, and WriteFileTextAsync should return a task, and be awaited.

If you are just writing strings you would find it easier to use the FileIO helper methods.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM