• SSIS hang with unhandle exception


    如果你的packages在执行的过程中有没有被捕获到的异常,sqldumper会跳出来获取这些异常信息输出,存在下面的目录中:

    C:Program FilesMicrosoft SQL Server110SharedErrorDumps

    文件有以.tmpmdmp结尾.

    SQLDUMPER_ERRORLOG.log

    通常这个时候整个package就会被hang,如果你使用Dtsdebughost.exe(即在VS)中测试时,

    如果你直接使用dtexec.exe来操作,可能dtexec就已经崩溃了.stop working.

    我的包中使用到了多线程进行数据加载,如果线程中出现了异常,package会在测试时hang,所以我就进行了下面的测试.

    我在Package中使用了一个scripttask,new 了三个线程执行一些简单的测试操作.

    我特意让子线程抛出一些测试异常,我们在主线程中无法捕获这些子线程抛出的异常.

    但是我使用appdomain.currentdomain.unhandleexception方法来捕获处理这些异常.

    第一次测试的结果是:

    sqldumper跳出来,然后pacakge就一直running,SSDT中显示包已经执行完成.但是其onPostExecute事件并未被执行.

    processinginfo中可以看到unhandleexception绑定的事件处理方法已经执行了.

    界面中一直hang住的情况,我分析是有些线程没有被中止

    然后我就开始了第二次尝试,

    在处理未捕获异常的事件处理方法中加入处理线程的方法,我让每一个线程在启动前都加入一个list<thread>对象.

    处理的时候,先捕获异常信息,然后输出线程的状态,最后abort线程.我发现task顺利完成了.

    第三次测试,我在Package的OnQueryCancel中加入一个scriptask,但其中故意生成一个异常,scripttask也会被hang住,

    因为我发现在package的执行过程中,onquerycancel事件会被不定期触发,只要我们的System::Cancel变量是false.

    在bookonline上查找相关onquercancel的说明,它会不定期触发,你可以通过设置system::cancel变量的值通知它停止运行,它给了你这样的一个机会,终止任务的执行.

    我想到了MSDN论坛上有一个人问题的问题,他说如果package的执行时长超过10分钟,就需要它自动停止,其实就可以使用类似这样的方法,如果package执行时长超过10分钟,就把它的System::Cancel值置为true即可.

    在package中的代码如下:

       

     bool isreuse = false;
            List<Thread> _listworkthreads = new List<Thread>();
            object internalsyncobj = new object();
            /// <summary>
            /// This method is called when this script task executes in the control flow.
            /// Before returning from this method, set the value of Dts.TaskResult to indicate success or failure.
            /// To open Help, press F1.
            /// </summary>
            public void Main()
            {
                // TODO: Add your code here
                AppDomain.CurrentDomain.UnhandledException += HandleException;
               
                Dts.TaskResult = (int)ScriptResults.Success;
    
                string mymsg = "thread :" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString()
                                 + " domainid:"
                                 + System.Threading.Thread.GetDomainID().ToString()
                             ;
                Dts.Events.FireInformation(0, "showmsg", mymsg, "", 0, ref isreuse);
    
                int times = 0;
                bool isused = false;
                while (times < 300)
                {
                    times++;
                    Dts.Events.FireInformation(0, "showmsg", times.ToString(), "", 0, ref isreuse);
                    if (times == 9 && !isused)
                    {
                        Dts.Events.FireInformation(0, "showmsg", "update var_threadcount to 2", "", 0, ref isreuse);
                        Dts.Variables["var_threadcount"].Value = 2;
                        //try { Dts.VariableDispenser.Reset(); }catch { }
                        isused = true;
                    }
                }
    
                runNewThread("test");
    
                Thread th = new Thread(
                obj =>
                {
                    throw new Exception("hello exception in thread");
                });
                lock (internalsyncobj) { _listworkthreads.Add(th); }
                th.Start();
                     
                System.Threading.Thread.Sleep(6 * 1000);
            }
    
            void runNewThread(string msg)
            {
                Thread th = new Thread(
                     obj =>
                     {
                         Dts.Events.FireInformation(0, "showmsg", msg, "", 0, ref isreuse);
                         string mymsg = "thread :" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString()
                             + " domainid:"
                             + System.Threading.Thread.GetDomainID().ToString()
                         ;
                         Dts.Events.FireInformation(0, "showmsg", mymsg, "", 0, ref isreuse);
    
                         Thread t = new Thread(() =>
                           {
                               throw new Exception("hello exception in child thread!");
                           });
                         lock (internalsyncobj) { _listworkthreads.Add(t); }
                         t.Start();
                     }
                     );
                lock (internalsyncobj) { _listworkthreads.Add(th); }
                th.Start(msg);
            
            }
            
            void HandleException(object sender, UnhandledExceptionEventArgs e)
            {
                Dts.Events.FireInformation(0, "UnhandleException", 
                    "sender:" + sender.ToString() +
                    "message:" + ((Exception)e.ExceptionObject).Message
                    , "", 0, ref isreuse);
    
                //handle child thread
              lock (internalsyncobj)
                {
                    Dts.Events.FireInformation(0,"AppdomainUnhandleException", "thread count:" + _listworkthreads.Count.ToString()
                        + " start to kill all child thread at time:" + DateTime.Now.ToString()
                    , "", 0, ref isreuse);
                    foreach (Thread th in _listworkthreads)
                    {
                        Dts.Events.FireInformation(0, "ThreadState", "thread state:" + th.ThreadState.ToString()
                         + DateTime.Now.ToString()
                    , "", 0, ref isreuse);
    
                        try {
                            th.Abort(); }
                        catch (Exception ex) { }
                    }
                }
           
    
            }
    View Code

       

    Looking for a job working at Home about MSBI
  • 相关阅读:
    JavaScript匿名函数的使用
    __construct __destory __call __get __set
    嵌入式学习
    动态加载script文件
    Android框架Volley使用:Post请求实现
    Android框架Volley使用:Get请求实现
    安卓开发笔记(三十五):Cardview的简单使用
    安卓开发笔记(三十四):Material Design框架实现优美的左侧侧滑栏
    Android APK反编译技巧全讲解
    Java数据结构(一):栈
  • 原文地址:https://www.cnblogs.com/huaxiaoyao/p/3738088.html
Copyright © 2020-2023  润新知