尝试读取或写入受保护的内存.这通常表明其他内存已损坏

Mon*_*RPG 7 c# wpf unhandled-exception memory-corruption access-violation

我真的不明白这个错误是如何发生的.请自行检查代码

    void dispatcherTimer_Tick(object sender, EventArgs e)
{
    string srUrl = lstLocalIndex[irLocalIndex] + lstMainIndex[irMainIndex].Replace("0;","");

    Task.Factory.StartNew(() =>
    {
        startNewWindow(srUrl);
    });

}


    void startNewWindow(string srUrl)
{
    NewWindowThread<TitleWindow, string>(c => new TitleWindow(c), srUrl);
}
Run Code Online (Sandbox Code Playgroud)

现在这段代码就是发生错误的地方.我还会附上截图

        private void NewWindowThread<T, P>(Func<P, T> constructor, P param) where T : Window
    {
        Thread thread = new Thread(() =>
        {
            T w = constructor(param);
            w.Show();
            w.Closed += (sender, e) => w.Dispatcher.InvokeShutdown();
            try
            {
                System.Windows.Threading.Dispatcher.Run();
            }
            catch
            {

            }
        });
        thread.SetApartmentState(ApartmentState.STA);
        try
        {
            thread.Start();
        }
        catch
        {

        }
    }
Run Code Online (Sandbox Code Playgroud)

此错误导致整个软件抛出错误并停止工作,即使我在新线程中调用它们:(

这行抛出错误 System.Windows.Threading.Dispatcher.Run();

请检查截图

在此输入图像描述

C#4.0 WPF

小智 1

您正在使用 lambda 作为线程函数。该 lambda 在新线程上调用。当线程实际创建时,它将查找您提供的参数,这是一个局部变量 srUrl,但是当发生这种情况时,您的函数(dispatcherTimer_Tick)已经退出,因此 srUrl 将位于堆栈的一部分中不再正确定义(因此出现访问冲突)。简单的解决方法是在类中定义一个变量并快速将 srLoc 填充到那里。更合适的解决方案是实际传递 srLoc 作为参数:

() =>
{
    startNewWindow(srUrl);
}
Run Code Online (Sandbox Code Playgroud)

变成

(Action<string>){x => {startNewWindow(x);},
            new object[] {srUrl}
Run Code Online (Sandbox Code Playgroud)

现在,为函数调用保存了函数引用和字符串的正确副本,并且在线程启动时原始 srUrl 超出范围并不重要。我不确定任务工厂是否允许要传递的参数数组。调度程序通常对此有超载,所以也许您想让您的窗口来处理这个问题。

现在您实际上执行了几次此操作,因此您可能需要在每次传递参数时包装参数。