C# 尝试读取或写入受保护的内存。这通常表明其他内存已损坏
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9982692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Attempted to read or write protected memory. This is often an indication that other memory is corrupt
提问by MonsterMMORPG
I really do not understand how is this error happening at this code. Please check the code yourself
我真的不明白这个错误是如何在这段代码中发生的。请自行检查代码
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);
}
Now this code is where the error happening. I will also attach screenshot
现在这段代码是错误发生的地方。我也会附上截图
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
{
}
}
This error causes whole software throw error and stop working even though i am calling them in new thread :(
即使我在新线程中调用它们,此错误也会导致整个软件抛出错误并停止工作:(
This line throwing error System.Windows.Threading.Dispatcher.Run();
这一行抛出错误 System.Windows.Threading.Dispatcher.Run();
Please check also screenshot
请检查截图


C# 4.0 WPF
C# 4.0 WPF
采纳答案by Nzc
You are using a lambda as a thread function. This lambda is called on a new thread. At the moment the thread is actually created, it will look for the argument you supply, which is a local variable srUrl, but by the time this happens your function (dispatcherTimer_Tick) has already exited, so srUrl will be in a part of the stack that is no longer properly defined (hence the access violation). The easy fix is to define a variable in the class and stuff the srLoc there quickly. A more proper solution is to actually pass the srLoc as argument:
您正在使用 lambda 作为线程函数。这个 lambda 在一个新线程上被调用。在实际创建线程的那一刻,它会查找您提供的参数,它是一个局部变量 srUrl,但是当发生这种情况时,您的函数 (dispatcherTimer_Tick) 已经退出,因此 srUrl 将位于堆栈的一部分不再正确定义(因此出现访问冲突)。简单的解决方法是在类中定义一个变量并快速填充 srLoc。更合适的解决方案是将 srLoc 作为参数实际传递:
() =>
{
startNewWindow(srUrl);
}
becomes
变成
(Action<string>){x => {startNewWindow(x);},
new object[] {srUrl}
Now the function reference and a proper copy of the string are saved for the function call, and it doesn't matter that the original srUrl is out of scope by the time the thread kicks in. I'm not sure whether the task factory allows the argument array to be passed. dispatchers normally have an overload for this, so maybe you want to let your window take care of this.
现在为函数调用保存了函数引用和字符串的正确副本,并且在线程启动时原始 srUrl 超出范围无关紧要。我不确定任务工厂是否允许要传递的参数数组。调度员通常对此有一个过载,所以也许你想让你的窗口来处理这个。
Now you actually do this a few times, so you may need to wrap the arguments each time they are passed.
现在你实际上这样做了几次,所以你可能需要在每次传递参数时包装它们。
回答by surfen
I had similar problem some time ago.
前段时间我遇到了类似的问题。
The error occurs because your window goes out of scope and Garbage Collector destroys it.
发生错误是因为您的窗口超出范围并且垃圾收集器将其销毁。
Using ShowDialog()should solve the issue. Note that doing this won't block other threads because the window will be modal in the calling thread only.
使用ShowDialog()应该可以解决问题。请注意,这样做不会阻塞其他线程,因为窗口仅在调用线程中是模态的。
private void NewWindowThread<T, P>(Func<P, T> constructor, P param) where T : Window
{
Thread thread = new Thread(() =>
{
System.Windows.Threading.Dispatcher.Run();
T w = constructor(param);
w.ShowDialog();
w.Dispatcher.InvokeShutdown();
});
thread.SetApartmentState(ApartmentState.STA);
try
{
thread.Start();
}
catch
{
// log&handle exceptions
}
}
回答by Joe Brunscheon
I have been battling this issue with a customer and here is what I found.
我一直在与客户解决这个问题,这是我发现的。
We are working on a WPF application that does a lot of threading and background worker processing. This exception suddenly started cropping up and I started doing some digging. I finally found the culprit after about an hour of investigating:
我们正在开发一个 WPF 应用程序,它执行大量线程和后台工作程序处理。这个异常突然开始出现,我开始做一些挖掘。经过大约一个小时的调查,我终于找到了罪魁祸首:
var worker = new BackgroundWorker();
worker.DoWork += (o, ea) => Dispatcher.BeginInvoke(new Action(() =>
{
//do some heavy processing here, plus UI work, then call another method.
//inside that other method, I found this:
var thread = new Thread(() =>
{
//do some heavy processing.
}) { IsBackground = true };
thread.Start();
}));
What appears to have been happening is that the background worker is finishing its work and returning from its execution. However, the thread that is created inside that background worker isn't done processing and returns only to find that the thread it was created on has already gone out of scope, thus resulting in the AccessViolationException.
似乎正在发生的事情是后台工作人员正在完成其工作并从执行中返回。但是,在后台工作线程中创建的线程没有完成处理,返回时才发现创建它的线程已经超出范围,从而导致 AccessViolationException。
In order to debug this, I would suggest paying close attention to where the exception happens and closely examining your call stack, which may or may not have been destroyed or lost depending upon whether or not you are inside a thread when the exception gets thrown.
为了调试这个,我建议密切注意异常发生的位置并仔细检查你的调用堆栈,它可能会或可能不会被破坏或丢失,这取决于抛出异常时你是否在线程内。

