3

在 VS 2008 中调试我的程序时,我遇到了以下错误:

CLR 在 60 秒内无法从 COM 上下文 0x34fc1a0 转换到 COM 上下文 0x34fc258。拥有目标上下文/单元的线程很可能要么进行非泵送等待,要么处理非常长时间运行的操作而不泵送 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();
    }

据我所知,计时器应该运行,经过然后再次初始化,我看不到死锁的本地原因。

我知道如何关闭此错误消息,但觉得这不是解决方案,而是掩盖了问题。

4

5 回答 5

5

如果您认为您绝对没有遇到死锁情况,您可以将其关闭:

Visual Studio 中的 Debug->Exceptions->Managed Debug Assistants 菜单并取消选中 ContextSwitchDeadlock

于 2008-12-02T16:48:13.200 回答
4

这是一个无限循环。您需要让您的应用程序至少每 60 秒发送一次消息,以防止发生此异常。尝试不时调用 System.Threading.Thread.CurrentThread.Join(10)。您还可以执行其他调用来让消息激增。

于 2009-03-04T22:34:53.537 回答
1

每次调用 InitialiseTimer 时,您似乎都在添加一个新的事件处理程序。这样, m_Timer_Elapsed 将被调用的次数与添加的次数一样多。您应该只添加一次事件处理程序。

于 2008-12-02T16:34:30.060 回答
1

如果您的应用程序挂起或即使在您取消选中 contextswitchdeadlock 框后也没有响应。将以下行放在方法或 for 循环调用之前。

在 C# 中

System.Windows.Forms.Application.DoEvents();

和 VB.NET / VB / ASP.NET

DoEvents()
于 2010-02-09T06:29:30.207 回答
0

几个想法/问题:

1)代码片段看起来像你的间隔是每 1 秒(不是评论中提到的 5 秒)。2)最大的问题是在RequestWork()做什么?

在不知道RequestWork()在做什么的情况下,我们无法真正评论您看到 ContextSwitchDeadlock 的原因。

关于这种方法需要考虑的事情 a) 需要多长时间?b) 它是否在访问 GUI 元素?

MSDN 对 Elapsed 的一些评论:

如果将 Timer 与用户界面元素(例如窗体或控件)一起使用,请将包含 Timer 的窗体或控件分配给 SynchronizingObject 属性,以便将事件封送至用户界面线程。

-和-

Elapsed 事件在 ThreadPool 线程上引发。如果 Elapsed 事件的处理持续时间超过 Interval,则该事件可能会在另一个 ThreadPool 线程上再次引发。因此,事件处理程序应该是可重入的。

我在想,既然你有一个 1 秒的计时器,你可能想看看 RequestWork 中发生了什么,看看它需要多长时间。

于 2009-01-28T22:54:34.417 回答