【问题标题】:Async when writing File in Windows 8在 Windows 8 中写入文件时异步
【发布时间】:2012-12-24 23:51:37
【问题描述】:

当我执行按钮单击事件并在打开时写入文本文件时,它仍然挂起 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"/>

有什么原因吗?

【问题讨论】:

  • 你能说明你如何/在哪里调用这些方法吗?也许在某个地方你对阻塞主线程的任务有一个等待调用?
  • 通过按钮事件点击调用。

标签: c# asynchronous winrt-xaml async-await


【解决方案1】:

你应该改变:

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

【讨论】:

    【解决方案2】:

    您编写的代码中存在一些错误。你不是在等待 WriteAsync,WriteFileTextAsync 应该返回一个任务,并被等待。

    如果您只是编写字符串,您会发现使用 FileIO 辅助方法更容易。

    【讨论】:

    • 那是我原来的帖子。我一直在等待这些方法。 UI仍然被阻止。我知道,但那是一次只写对吗?如果我想在写的时候打开文件怎么办。
    • 您仍然需要 WriteFileTextAsync 来返回 Task not void,并等待该调用。切换到 FileIO,它更容易!
    • 如果我错了,请纠正我,但 FileIO 只会在一个巨大的字符串中写入一次大的时间,对吧?
    • 好的,我尝试了您的建议,将其更改为任务。它没有做任何改变。我想知道是谁在阻止它。
    • 不,你可以使用追加行
    猜你喜欢
    • 1970-01-01
    • 2011-02-06
    • 2017-06-07
    • 2013-03-15
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多