简体   繁体   中英

C# - Thread.Sleep() doesn't seem to work in my Windows Service

I have access to a particular API that enforces a speed limit of around 3 API calls per second. I'm creating a Windows Service using C#, and I figured if I just place a " Thread.Sleep(4000) " in between calls, that would delay each call by 4 seconds. Well, I had a " for " loop, looping 10 times, for testing. Within a second or so, it inserted all 10 records pulled from the API into my database. So, the Thread.Sleep(4000) wasn't being obeyed. I've read that Thread.Sleep() only works on the current thread. I don't know much about threading, but I was hoping one of you could tell me what I'm doing wrong, or at least suggest an alternative approach for obeying API traffic laws. Here's the relevant part of my code:

    using (SqlConnection connection = new SqlConnection("Data Source=localhost;Initial Catalog=*****;Integrated Security=true;"))
    {
        for (int i = 0; i < 10; i++)
        {
            movie = api.GetMovieInfo(i);
            Thread.Sleep(4000);
            if (string.IsNullOrEmpty(movie.title))
                continue;
            string queryString = string.Format("insert into movie values ('{0}')", movie.title);

            SqlCommand command = new SqlCommand(queryString, connection);
            try
            {
                connection.Open();
                command.ExecuteNonQuery();
                connection.Close();
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
    }

It could be possible that you are seeing this behavior because your call to Thread.Sleep occurs in the using statement. Although I would still expect it to take at least four seconds and you stated that in only one second all of the 10 records were inserted. You could try to remove the call to Thread.Sleep from the using statement to see if the behavior improves...

see: C# exiting a using() block with a thread still running onthe scoped object

I do think that the Threading.Timer is a better option, but I would also think that Thread.Sleep should work as well:

    for (int i = 0; i < 10; i++)
    {
        DoAPIWork();
        Thread.Sleep(4000);
    }

    private void DoAPIWork()
    {
        using (SqlConnection connection = new SqlConnection("Data Source=localhost;Initial Catalog=*****;Integrated Security=true;"))
        {
            movie = api.GetMovieInfo(i);

                if (string.IsNullOrEmpty(movie.title))
                    continue;
                string queryString = string.Format("insert into movie values ('{0}')", movie.title);

                SqlCommand command = new SqlCommand(queryString, connection);
                try
                {
                    connection.Open();
                    command.ExecuteNonQuery();
                    connection.Close();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }
        }
    }

Try executing it on a new Thread

For example

for(int i = 0; i < 10; i++)
{
     Thread executionThread = new Thread(() =>
     {
         //Call your api process here
         DoWork();
     });
     executionThread.Start();
     // This stops the current thread and wait for the executionThread
     executionThread.Join();
}

and then let your DoWork() handle the sleep.

public void DoWork()
{
   Thread.Sleep(4000);
   // Do actual work here
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM