c#while(true)循环for watch文件夹似乎导致Stackoverflowexception

时间:2016-05-18 12:54:08

标签: c# stack-overflow

我需要为监视文件夹过程设置无限循环。我让它通过数据表每30秒执行一次Parallel.ForEach(iterate.AsEnumerable(), drow =>方法。但是,使用while(true)循环似乎会导致堆栈溢出异常。

我想知道是否有更好的方法可以帮助我消除异常的无限循环。

更新1

从SQL数据库填充数据表,并以Windows窗体的形式显示给用户。数据表具有用户可以编辑的监视文件夹位置。这就是我正在迭代的内容。这些文件夹是通过SOAP Web服务访问的。

这里是代码 - 对不起它很长但我认为你们都需要看到所有这些内容。如果您需要进一步澄清,请与我们联系。

点击按钮

启动此过程
    public partial class HomePage : Form
{
        public void button1_Click(object sender, EventArgs e)
            {
                //set serviceStop to 0 (false)

                string connectionString = @"Data Source=FCMONITOR\AVIDAUTO;Initial Catalog=InterplayWatchFolder;Integrated Security=True";
                using (SqlConnection connection = new SqlConnection(connectionString))


                {
                    SqlCommand setCancelRequest = new SqlCommand("UPDATE SERVICE_STOP SET SERVICE_STOP_REQUESTED = 0");
                    setCancelRequest.CommandType = CommandType.Text;
                    setCancelRequest.Connection = connection;
                    connection.Open();
                    setCancelRequest.ExecuteNonQuery();
                    connection.Close();
                }


                //start service
                initiateThread();




            }

            private void initiateThread()
            {


                Console.WriteLine("Initiating new check");
               System.Threading.Tasks.Task newJobTask = System.Threading.Tasks.Task.Factory.StartNew(() =>
                {
                repeater();
            }



        private void repeater()
            {

                while(true)

                {


                    string serviceStop = "False";

                    //check if service stop was requested
                    string connectionString = @"Data Source=FCMONITOR\AVIDAUTO;Initial Catalog=InterplayWatchFolder;Integrated Security=True";
                    using (SqlConnection connection = new SqlConnection(connectionString))

                    {
                        SqlDataReader stopServiceRequestedReader = null;
                        SqlCommand getStopServiceRequested = new SqlCommand("SELECT [SERVICE_STOP_REQUESTED] FROM SERVICE_STOP", connection);
                        getStopServiceRequested.CommandType = CommandType.Text;
                        connection.Open();
                        stopServiceRequestedReader = getStopServiceRequested.ExecuteReader();
                        while (stopServiceRequestedReader.Read())
                        {
                            serviceStop = stopServiceRequestedReader["SERVICE_STOP_REQUESTED"].ToString();

                        }
                        connection.Close();
                    }


                        //check if service was stopped
                        if (serviceStop == "False")
                        {
                        Thread.Sleep(30000);


                        System.Threading.Tasks.Task newJobTask = System.Threading.Tasks.Task.Factory.StartNew(() =>
                            {
                                executeThreadRunService();
                                garbage garbage = new garbage();
                                garbage.Dispose();



                            }
                            );
                        }
                        else
                        {
                            garbage garbage = new garbage();
                            garbage.Dispose();

                        break;
                            Thread.CurrentThread.Join();
                        }

        }

    private void executeThreadRunService()
            {


                {



                    //iterate workflow across table
                    DataTable iterate = (DataTable)interplaySetupView.DataSource;

                    //execute service in parallel

                    {


                        Parallel.ForEach(iterate.AsEnumerable(), drow =>

                        {



                            //Set Variables
                            string insertDeliniator = "/"; //extra needed to build URI
                            string insertInterplay = "interplay://"; //extra info needed to build URI


                            string interplayEngineHostname = drow["Interplay_Engine_Hostname"].ToString();
                            string interplayWatchFolder = insertInterplay + drow["Interplay_Engine_Hostname"].ToString() + insertDeliniator + drow["Interplay_Watch_Folder"].ToString();
                            string safeForTranscodingFolder = insertInterplay + drow["Interplay_Engine_Hostname"].ToString() + insertDeliniator + drow["Interplay_Safe_Folder"].ToString();
                            string safeForTranscodingSubmitURI = "interplay://Interplay/" + drow["Interplay_Safe_Folder"].ToString();
                            string transferEngineHostname = drow["Transfer_Engine_Hostname"].ToString();
                            string transferPlaybackDevice = drow["Transfer_Profile"].ToString();
                            string transcodingProfile = drow["Transcoding_Profile"].ToString();
                            string storeInterplayUsername = interplayUsername.Text.ToString();
                            string storeInterplayPassword = interplayPasswordInput.Text.ToString();
                            string workflowName = drow["Workflow_Name"].ToString();
                            string catDVEnabled = drow["CATDV_ENABLED"].ToString();
                            string catDVXMLDumpLocation = drow["CATDV_XML_DUMP_LOCATION"].ToString();
                            string xmlMetadataDumpLocation = drow["METADATA_XML_DUMP_LOCATION"].ToString();
                            string rewriteSequenceMetadata = drow["REWRITE_SEQUENCE_METADATA"].ToString();






                            System.Threading.Tasks.Task newWatchTask = System.Threading.Tasks.Task.Factory.StartNew
                                (
                                    () =>



                                runService.executeWatchService
                                    (
                                interplayEngineHostname,
                                interplayWatchFolder,
                                safeForTranscodingFolder,
                                safeForTranscodingSubmitURI,
                                transcodingProfile,
                                transferEngineHostname,
                                transferPlaybackDevice,
                                interplayUsernameInput.Text.ToString(),
                                interplayPasswordInput.Text.ToString(),
                                workflowName,
                                catDVEnabled,
                                catDVXMLDumpLocation,
                                xmlMetadataDumpLocation,
                                rewriteSequenceMetadata




                                    ) );

                            garbage garbage = new garbage();
                            garbage.Dispose();

                            Thread.CurrentThread.Join();
                        }
}


//another class where the runService method is

        public class runService
        {

            public static void executeWatchService(
                string interplayEngineHostname,
                string interplayWatchFolder,
                string safeForTranscodingFolder,
                string safeForTranscodingSubmitURI,
                string transcodingProfile,
                string transferEngineHostname,
                string transferPlaybackDevice,
                string interplayUsername,
                string interplayPassword,
                string workflowName,
                string catDVEnabled,
                string catDVXMLDumpLocation,
                string xmlMetadataDumpLocation,
                string rewriteSequenceMetadata

                )


            {

                {

                    {





                        //Find if there is a new sequence
                        //If none, method exits
                        WatchForNewSequence watchForNewSequence = new WatchForNewSequence();
                        WatchForNewSequence.returnMOBIDandJobName MOBIDandJobNameResults = watchForNewSequence.searchForNewSequence(
                                interplayWatchFolder,
                                interplayUsername,
                                interplayPassword,
                                workflowName,
                                safeForTranscodingFolder);
                        string returnOriginalSequenceMOBID = MOBIDandJobNameResults.returnOriginalSequenceMOBID;
                        string returnJobName = MOBIDandJobNameResults.returnJobName;


//another class where the WatchForNewSequence method is

    class WatchForNewSequence
    {

        public struct returnMOBIDandJobName
        {
            public string returnOriginalSequenceMOBID;
            public string returnJobName;
        }


        public returnMOBIDandJobName searchForNewSequence(
            string interplayWatchFolder,
            string interplayUsername,
            string interplayPassword,
            string workflowName,
            string safeForTranscodingFolder
            )

        {


                string originalSequenceMOBID = "empty";
                string jobName = "empty";

                Console.WriteLine("Checking for new sequence for " + interplayWatchFolder);
                AssetsPortTypeClient port = new AssetsPortTypeClient();
                UserCredentialsType creds = new UserCredentialsType();
                creds.Username = interplayUsername;
                creds.Password = interplayPassword;

                //parameters currenlty set for sequences only
                //masterclip do not send in this verison
                SearchType param = new SearchType();
                param.MaxResults = 1;
                param.InterplayPathURI = interplayWatchFolder;
                param.SearchGroup = new SearchGroupType();
                param.SearchGroup.Operator = "AND";
                param.SearchGroup.AttributeCondition = new AttributeConditionType[1];
                param.SearchGroup.AttributeCondition[0] = new AttributeConditionType();
                param.SearchGroup.AttributeCondition[0].Condition = "EQUALS";
                param.SearchGroup.AttributeCondition[0].Attribute = new AttributeType();
                param.SearchGroup.AttributeCondition[0].Attribute.Name = "Type";
                param.SearchGroup.AttributeCondition[0].Attribute.Group = "SYSTEM";
                param.SearchGroup.AttributeCondition[0].Attribute.Value = "sequence";


                //send request
                SearchRequest request = new SearchRequest();
                request.UserCredentials = creds;
                request.Search = param;

                garbage garbage = new garbage();
                garbage.Dispose();
                GC.Collect();
                GC.WaitForFullGCComplete();


            SearchResponseType response = port.Search(creds, param);

                //check if there is any sequences
                if (response.Results.Length > 0)
                {

                    //designate that we want the MOB ID to be returned as a result of this method
                    foreach (AssetDescriptionType ad in response.Results)
                    {
                        foreach (AttributeType att in ad.Attributes)
                        {
                            if (att.Name == "MOB ID")
                            {
                                originalSequenceMOBID = att.Value;

                            }
                            if (att.Name == "Display Name")
                        {
                            jobName = att.Value;

                            //The original sequence MOBID is found and returned from the WatchForNewSequence Class
                            Console.WriteLine(originalSequenceMOBID + "...." + jobName);

                        }
                        garbage garbage2 = new garbage();
                        garbage.Dispose();

                    }
                    }
                }
                else
                {
                    originalSequenceMOBID = "No_Sequence";
                    Console.WriteLine("No new sequence for " + interplayWatchFolder + " -- exiting");

                    garbage garbage3 = new garbage();
                    garbage.Dispose();
                    Thread.CurrentThread.Join();




                }
                //no new sequence, methods exit and program ends
                if (response.Errors != null)
                {
                    foreach (ErrorType watchForNewSequenceError in response.Errors)
                    {
                        Console.WriteLine("ERROR: " + watchForNewSequenceError.Message + watchForNewSequenceError.Details + "at" + watchForNewSequenceError.InterplayURI);
                    }
                }


            returnMOBIDandJobName returnMOBIDandJobName = new returnMOBIDandJobName();
            returnMOBIDandJobName.returnOriginalSequenceMOBID = originalSequenceMOBID;
            returnMOBIDandJobName.returnJobName = jobName;

            return returnMOBIDandJobName;

                //return originalSequenceMOBID to Program
            //return originalSequenceMOBID;





        }


    }

1 个答案:

答案 0 :(得分:1)

确保处置实现IDisposable并在循环内创建的任何对象。我看到StackOverflowExceptions是由对象没有正确处理引起的。

例如,SqlDataReader stopServiceRequestedReader永远不会关闭或处置。