You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP中RichEditBox调用LoadFromStream触发System.AccessViolationException

问题描述

我有一个RichEditBox控件,内容从文件加载。极少情况下,调用相关方法时会抛出如下异常:

System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'

相关加载代码:

var RAS = await TXTFile.OpenAsync(FileAccessMode.ReadWrite);

RTB.Document.LoadFromStream(TextSetOptions.FormatRtf, RAS);

使用DispatcherTimer连续快速调用该方法可复现此bug,但应用需运行约10至15分钟才会出现。

补充的自动保存相关代码:

private void REB_SelectionChanged(object Sender, RoutedEventArgs EvArgs)
{
    //自动保存
    if (AutoSaveSwitch.IsOn == true)
    {
        TriggerAutosave();
    }
}

public void TriggerAutosave()
{
    if (DTSave.IsEnabled != true) DTSave.Start();
}
private void DTSave_Tick(object sender, object e)
{
    if (AutoSaveSwitch.IsOn == true && TXTFile != null)
    {
        try
        {
            if (TXTFile != null)
            {
                if (AutoSaveSwitch.IsOn == true)
                {
                    AutosaveWritingToFile();
                }
                else
                {
                    SaveIndicatorGrid.Visibility = Visibility.Visible;
                }
            }
            else
            {
                SaveIndicatorGrid.Visibility = Visibility.Visible;
            }
        }
        catch (Exception EX)
        {

        }
    }
    else
    {
        DTSave.Stop();
    }
}

readonly DispatcherTimer DTSave = new DispatcherTimer();

public MainPage()
{
    InitializeComponent();
    DTSave.Interval = new TimeSpan((int)1.5);
    DTSave.Tick += DTSave_Tick;
}
解决方案分析

1. 修复资源泄漏问题

加载文件时未正确释放流资源,并发操作下易引发内存冲突。用using语句确保流自动释放:

using (var RAS = await TXTFile.OpenAsync(FileAccessMode.ReadWrite))
{
    RTB.Document.LoadFromStream(TextSetOptions.FormatRtf, RAS);
}

2. 修正定时器间隔设置

原代码中TimeSpan((int)1.5)是按ticks计算,几乎瞬间触发,会导致高频并发操作。改为设置秒级间隔:

// 设置为1.5秒
DTSave.Interval = TimeSpan.FromSeconds(1.5);

3. 添加并发锁保护共享资源

自动保存和加载操作可能同时访问文件或RichEditBox文档,需加锁避免冲突:
在类中新增锁对象:

private readonly object _fileLock = new object();

修改加载代码:

lock (_fileLock)
{
    using (var RAS = await TXTFile.OpenAsync(FileAccessMode.ReadWrite))
    {
        RTB.Document.LoadFromStream(TextSetOptions.FormatRtf, RAS);
    }
}

修改自动保存方法(假设AutosaveWritingToFile是写文件逻辑):

private void AutosaveWritingToFile()
{
    lock (_fileLock)
    {
        // 原有的写文件代码
    }
}

4. 完善异常处理

原代码捕获异常后直接忽略,不利于排查问题,添加日志记录:

catch (Exception ex)
{
    Debug.WriteLine($"自动保存异常: {ex.Message}\n{ex.StackTrace}");
}

5. 优化定时器启动逻辑

改用IsRunning判断定时器状态,避免重复启动:

public void TriggerAutosave()
{
    if (!DTSave.IsRunning) 
        DTSave.Start();
}

内容的提问来源于stack exchange,提问作者Ivirius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:02:56