在VS 2008中调试我的程序时,我遇到了以下错误:
CLR无法从COM上下文0x34fc1a0过渡到COM上下文0x34fc258 60秒。拥有目标上下文/公寓的线程很可能是在非抽空等待或处理非常长时间运行的操作而不抽取Windows消息。这种情况通常会对性能产生负面影响,甚至可能导致应用程序变得无响应或内存使用量随时间不断累积。为了避免这种情况
即使代码只包含一个简单的C#计时器,它似乎仍然是死锁:请参阅下面的代码段:
private void RequestWork()
{
// The timer will be re-intialised if there are still no wating jobs in the database
StopTimer();
// assign all the threads some work
InitialiseTimer();
}
/// <summary>
/// Initialise a timer with a timer interval configured from app.config. Enable the timer and
/// register an appropriate event handler
/// </summary>
private void InitialiseTimer()
{
if (m_Timer == null)
{
// look up the default backoff time from the config
string backOffInt = ConfigurationSettings.AppSettings["BackOffInterval"];
int backoffInterval = 1000;
m_Timer = new System.Timers.Timer();
// set the timer interval to 5 seconds
m_Timer.Interval = backoffInterval;
m_Timer.Elapsed += new ElapsedEventHandler(m_Timer_Elapsed);
}
m_Timer.Enabled = true;
}
private void StopTimer()
{
if (m_Timer != null)
{
m_Timer.Enabled = false;
}
}
void m_Timer_Elapsed(object p_Sender, ElapsedEventArgs p_E)
{
RequestWork();
}
据我所知,计时器应该运行,经过然后再次初始化,我看不出局部的死锁原因。
我知道如何关闭此错误消息但感觉这不是解决方案,而是掩盖了问题。
答案 0 :(得分:5)
如果你认为你肯定没有陷入僵局,你可以关闭它:
Debug-&gt; Exceptions-&gt; Visual Studio中的托管调试助手菜单,取消选中ContextSwitchDeadlock
答案 1 :(得分:4)
这是一个无限循环。您需要让应用程序每60秒至少抽一次消息,以防止发生此异常。 尝试偶尔调用System.Threading.Thread.CurrentThread.Join(10)。还有其他一些电话可以让消息消失。
答案 2 :(得分:1)
每次调用InitialiseTimer时,似乎都在添加新的事件处理程序。这样m_Timer_Elapsed将被添加多次调用。 您应该只添加一次事件处理程序。
答案 3 :(得分:1)
如果您的应用程序在取消选中contextswitchdeadlock的框后仍然挂起或不响应。在调用方法或循环之前放入以下行。
在C#中
System.Windows.Forms.Application.DoEvents();
和VB.NET / VB / ASP.NET
DoEvents()
答案 4 :(得分:0)
夫妻的想法/问题:
1)代码片段看起来像你的间隔是每1秒(不是评论中提到的5)。
2)最大的问题是RequestWork()
在做什么?
在不知道RequestWork()
正在做什么的情况下,我们无法真正评论您为什么会看到ContextSwitchDeadlock。
关于这种方法需要考虑的事情 a)需要多长时间? b)是否正在访问GUI元素?
一些MSDN对Elapsed的评论:
如果您与用户一起使用Timer 界面元素,例如表单或 控制,分配表格或控制 包含Timer的定时器 SynchronizingObject属性,这样 该事件被封送给用户 界面线程。
- 和 -
Elapsed事件在a上引发 ThreadPool线程。如果处理 经历的事件持续时间超过 间隔,可能会引发事件 再次在另一个ThreadPool线程上。 因此,事件处理程序应该是 折返。
我在想,因为你有1秒计时器,你可能想看看RequestWork中发生了什么,看看它花了多长时间。