开发者

C# compact framework : multi thread cause delay?

In my mobile app, I want to load all images from an arraylist of links. For each link I create a thread and make httpwebrequest. The problem is that my app run not smooth. It seems to get a delay every time I create new thread and when thread done(when thread done I'll draw the download img onto background). Here's my code:

            for (int i = 0; i < NumbersOfImg; i++)
            {
                if (i < ImgObjArr.Count)
                {
                    ThreadStart myThread = new ThreadStart(getUrlImg);
                    Thread t = new Thread(myThread);
                    t.Start();
                }
            }


     private void getUrlImg()
     {
            MyImage mycurrentImg = (MyImage)ImgObjArr[curre开发者_运维知识库ntMyImg];
            if (currentMyImg < ImgObjArr.Count - 1)
                currentMyImg++;
            myRequest = (HttpWebRequest)WebRequest.Create(mycurrentImg.ImageLink);
            myResponse = (HttpWebResponse)myRequest.GetResponse();

            Stream ImgStream = myResponse.GetResponseStream();
            mycurrentImg.FullImg = new Bitmap(ImgStream);

            this.BeginInvoke(new EventHandler(ImageUpdate));
    }

and method ImageUpdate() will draw the Image. And when app navigate to next row, I will create numbers of threads to continue make webrequest. And delay happen when the old thread not complete but I create new threads. So any suggestion why my app had delay? Thanks in advance.


Two possible causes for the slowness:

  1. Depending on the value of ImgObjArr.Count, the code in the question could create a large number of threads, all hogging the CPU. The thread code itself is mostly harmless -- they wait for HTTP responses to come back. If a large number of them is run simultaneously, however, you could get CPU peaks that could slow down the UI. That can happen when the requests are being sent, and when responses start coming back and the code creates the Bitmap objects. Context switching has a cost too.

    What number of threads is too high depends on the horsepower of the CPU in question. Given that this is a compact-framework question, that would be the lower-end of the spectrum. You might want to consider limiting the number of background threads to a fixed pool size. Some number between 2-4 might be right. Note that you will not gain much benefit from more threads if the framework limits the number of outgoing connections anyway. (there should be a default limit set by the framework, 2 connections I believe, which you can change. The OS may set a limit too)

  2. The code inside ImageUpdate executes in the UI thread of the app. Any time spent there is time not available for processing input. This directly contributes to UI delays. If there is any code there that could be pushed into the background thread, that would be a worthwhile exercise. If all code that could be move to the background was already moved, reducing the number of background threads could still help, as that reduces the chance of multiple bitmaps hitting the UI thread at the same time and creating chained delays.


Creating a new thread is actually quite slow, and the more threads you have running at a time on a single processor system the longer each thread takes to operate once started. What you actually need is to limit the number of thread to something sensible and to only start the threads once and from then on just reused them.

Actually Microsoft has already done all the hard work of managing a pool of threads for this kind of task it is called the thread pool. You use it as follows:

for (int i = 0; i < NumbersOfImg; i++)
{
    if (i < ImgObjArr.Count)
    {
        ThreadPool.QueueUserWorkItem(getUrlImg)
    }
}


 private void getUrlImg(object state)
 {
     MyImage mycurrentImg = (MyImage)ImgObjArr[currentMyImg];
     if (currentMyImg < ImgObjArr.Count - 1)
         currentMyImg++;
     myRequest = (HttpWebRequest)WebRequest.Create(mycurrentImg.ImageLink);
     myResponse = (HttpWebResponse)myRequest.GetResponse();

     Stream ImgStream = myResponse.GetResponseStream();
     mycurrentImg.FullImg = new Bitmap(ImgStream);

     this.BeginInvoke(new EventHandler(ImageUpdate));
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜