【问题标题】:Is it some way to do async code for write to Stream?是否可以通过某种方式执行异步代码以写入 Stream?
【发布时间】:2017-02-07 11:37:08
【问题描述】:

我写了一些 WPF 编辑器,用来显示文本。 但是文本存储在Stream

所以,这里是 XAML 代码:

<TextBox Text="{Binding ObjectViewModel.Text,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />

我将UpdateSourceTrigger 设置为PropertyChanged,因为用户可以在此编辑器中读写一些文本;

这里的代码读取和写入文本(作为流):

public String Text
{
    get
    {    
        var sr = new StreamReader(StreamObject.text, Encoding.UTF8, true);
        return sr.ReadToEnd();
    }

    set
    {
        lock (_lockObject)
        {
            var str = value;
            var textStream = new MemoryStream();
            using (var writer = new BinaryWriter(textStream, Encoding.UTF8, true))
            {                                           
                writer.Write(Encoding.UTF8.GetBytes(str));
            }
            textStream.Position = 0;
            StreamObject.text = null;
            StreamObject.text = textStream;
            textStream.Close();
        }
    }
}

因此,当用户输入新的字码时,写入流新数据(清除旧流并创建新流)。

但它的性能很慢。 我应该使用async(以某种方式)还是其他方法来提高性能?

我知道,可以使用LostFocus 属性,但这样用户应该失去TextBox 的焦点。

【问题讨论】:

  • 为什么首先将文本存储在 Stream 中?
  • @Clemens,它存储在 DB。按设计
  • 然后在将其存储到数据库之前对其进行一次转换,而不是在每次击键时进行转换。

标签: c# wpf stream


【解决方案1】:

我应该使用异步(以某种方式)还是其他方法来提高性能?

确实有一个async 版本的ReadToEnd 方法称为ReadToEndAsync,但它实际上不会使您的代码更快,并且您不能从属性调用它,因为属性不能标记为async

每次更改属性时,在源属性的 getter 和相同的 setter 中创建新的 Stream 是没有意义的。

您应该从流中读取一次,例如在视图模型的构造函数或命令的 Execute 方法中,然后设置string 属性的值。然后在您实际需要将其保存到数据库时将string 转换回流一次,例如:

class ViewModel
{
    public ViewModel()
    {
        using (var sr = new StreamReader(StreamObject.text, Encoding.UTF8, true))
            Text = sr.ReadToEnd();
    }

    //this method is called when your "Save" button or similar is clicked
    public void SaveToDb()
    {
        lock (_lockObject)
        {
            var str = value;
            using (textStream = new MemoryStream())
            {
                using (var writer = new BinaryWriter(textStream, Encoding.UTF8, true))
                {
                    writer.Write(Encoding.UTF8.GetBytes(str));
                }
                textStream.Position = 0;
                StreamObject.text = null;
                StreamObject.text = textStream;
            }
        }
    }

    public String Text
    {
        get;set;
    }
}

源属性本身不应该知道有关流的任何信息。

【讨论】:

  • 嗯,谢谢你的好策略。我将使用其中的“阅读”部分。但是,在我的编辑器中,当StreamObject.text 修改时,保存按钮会激活。
  • 您应该修改它以在修改 Text 属性时激活它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-03
  • 2018-11-16
  • 2017-04-28
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
  • 2021-01-05
相关资源
最近更新 更多