ahmed_sa Ответов: 1

Как запустить запрос на основе многопоточности с помощью функции clr spexecuteparallel ?


Я работаю над visual studio 2019 asp.net ядро 2.2 и sql server 2012
Мне нужно запускать запрос каждые 2 секунды работать в фоновом режиме только на основе 4 потоков
ниже приводится функция CLR, но я должен применять приведенный ниже код на asp.net основной
так что как вызвать функцию spExecuteParallel под действием контроллера
как это:
public Actionresult  executequery()
{
write here calling clr function
}

так что мой вопрос
Как применить функцию clr на asp.net ядро 2
или есть какая-то вещь, которая может сделать это на asp.net сердечник

спасибо

Что я уже пробовал:

class ExecuteSQL
    {
        private List<string> oExecuteErrors;
        private object oExecuteLocker;
        private string sExecuteServer;
        private string sExecuteDB;
        private string sExecuteTSQL;
        private int iExecuteRetries;

        public ExecuteSQL(string sServer, string sDB, string sTSQL,
        int iRetries, ref List<string> oErrors, ref object oLocker)
        {
            this.sExecuteServer = sServer;
            this.sExecuteDB = sDB;
            this.sExecuteTSQL = sTSQL;
            this.iExecuteRetries = iRetries;
            this.oExecuteErrors = oErrors;
            this.oExecuteLocker = oLocker;
        }

        public void Process()
        {
            int iTries = 1;
            SqlConnection oConn = new SqlConnection();

        Retry:
            oConn = new SqlConnection("Data Source=" + sExecuteServer +
            ";Initial Catalog=" + sExecuteDB + ";Integrated Security=SSPI;");
            try
            {
                oConn.Open();

                if (oConn.State == ConnectionState.Open)
                {
                    SqlCommand oCmd = oConn.CreateCommand();
                    oCmd.CommandText = sExecuteTSQL;
                    oCmd.CommandTimeout = 0;
                    oCmd.ExecuteNonQuery();

                    oCmd.Dispose();
                    oConn.Close();
                    oConn.Dispose();
                }
                else
                {
                    throw new Exception("SQL Server not Found or Unable to Connect to SQL Server");
                }
            }
            catch (Exception ex)
            {
                if (oConn.State != ConnectionState.Closed) oConn.Close();
                oConn.Dispose();

                if (iTries <= iExecuteRetries)
                {
                    Thread.Sleep(5000);
                    iTries += 1;
                    goto Retry;
                }
                else
                {
                    lock (oExecuteLocker)
                    {
                        char cSpace = char.Parse(" ");
                        oExecuteErrors.Add(this.sExecuteDB.PadRight(16, cSpace) + " : " + ex.Message);
                    }
                }
            }
        }
    }
}

namespace SqlServerProjectSp
{
    public partial class StoredProcedures
    {
        [Microsoft.SqlServer.Server.SqlProcedure]
        public static SqlInt32 spExecuteParallel(string DB, int MaxDOP, string TSQL, int msDelay, int Retries)
        {
            SqlConnection oConn = new SqlConnection();
            SqlCommand oCmd = new SqlCommand();
            List<string> oErrorString = new List<string>();
            object oLocker = new object();
            string sServer = null;

            List<Thread> oThread = new List<Thread>();
            StringCollection sStopped = new StringCollection();
            if(string.IsNullOrEmpty(TSQL))
            {
                return 0;
            }
            // Get Server Instance Name
            oConn = new SqlConnection("context connection = true;");
            oConn.Open();

            oCmd = oConn.CreateCommand();
            oCmd.CommandText = "SELECT @@SERVERNAME";
            sServer = oCmd.ExecuteScalar().ToString();

            oCmd.Dispose();
            oConn.Close();
            oConn.Dispose();

            // Execute Threads
            int iCurrentThread = 0;
            while (iCurrentThread < MaxDOP)
            {
                ExecuteSQL Executer = new ExecuteSQL
                (sServer, DB, TSQL.Replace("?", DB.ToString().Trim()), Retries, ref oErrorString, ref oLocker);

                Thread oItem = new Thread(Executer.Process);
                oItem.Name = "ExecuteSQL " + DB.ToString().Trim();
                oItem.Start();
                oThread.Add(oItem);

                SqlContext.Pipe.Send(DateTime.Now.ToLongTimeString() +
                " : Start : " + oItem.Name.Replace("ExecuteSQL ", ""));
                Thread.Sleep(msDelay);

                while (RunningThreads(ref oThread, ref sStopped) >= MaxDOP)
                {
                    Thread.Sleep(1000);
                }
                iCurrentThread++;
            }

            // Wait for all Threads to Stop
            while (RunningThreads(ref oThread, ref sStopped) > 0)
            {
                Thread.Sleep(1000);
            }
            SqlContext.Pipe.Send("All Thread have Stopped with " +
            oErrorString.Count.ToString() + " Error/s ");

            if (oErrorString.Count > 0)
            {
                foreach (string sIndividualErrors in oErrorString)
                {
                    SqlContext.Pipe.Send(sIndividualErrors.ToString());
                }

                throw new Exception("Error Occurred.");
            }

            return 0 - oErrorString.Count;
        }

        public static int RunningThreads(ref List<Thread> oThread, ref StringCollection oStops)
        {
            int iRunningCount = 0;

            foreach (Thread oIndividualThread in oThread)
            {
                if (oIndividualThread.IsAlive)
                {
                    iRunningCount += 1;
                }
                else if (!oStops.Contains(oIndividualThread.Name))
                {
                    oStops.Add(oIndividualThread.Name);
                    SqlContext.Pipe.Send(DateTime.Now.ToLongTimeString() + " : Stop  : " + oIndividualThread.Name.Replace("ExecuteSQL ", ""));



                }
            }
            return iRunningCount;
        }
    }
}

Richard Deeming

Ваш ExecuteSQL класс заставит вас написать код, который уязвим для SQL-инъекция[^]. Вам нужно изменить его, чтобы разрешить правильную передачу параметров в запрос.

Также непонятно что именно spExecuteParallel то, что вы собираетесь делать с полученными результатами.

1 Ответов

Рейтинг:
2

RickZeeland

Может быть, эта статья CodeProject будет Вам полезна: Выполнение хранимых процедур параллельно[^]
Дело не в этом .Однако чистое ядро ...


ahmed_sa

Я уже получил этот код из этой статьи не могли бы вы помочь мне реализовать его на asp.net ядро 2.2

RickZeeland

Боюсь, у меня недостаточно опыта в этом деле. ASP.NET ядро, извините, может быть, кто-то еще может помочь или вы можете попробовать StackOverflow.