0

我有一个在 Windows CE/WindowsMo​​bile 6.1 中没有明显原因的应用程序非常慢,该应用程序直接使用线程,我正在尝试调查这是问题的原因,我编写了一个简单的程序:

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace SmartDeviceProject6
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime mtStart = DateTime.Now;
            System.Diagnostics.Debug.WriteLine("{0} MainThread - START", mtStart.ToString("MM/dd/yyyy hh:mm:ss.fff tt"));

            System.Diagnostics.Debug.WriteLine("Main Thread - Starts Here!");
            Thread t = new Thread(WriteY);          // Kick off a new thread
            t.Start();                               // running WriteY()

            // Simultaneously, do something on the main thread.
            for (int i = 0; i < 250; i++)
            {
                Console.Write("x");
                System.Diagnostics.Debug.WriteLine("x");
                System.Diagnostics.Debug.WriteIf(i == 249, "X is OVER");
                if (i == 50)
                {
                    System.Diagnostics.Debug.WriteLine("MAIN - sleep");
                    //Thread.Sleep(1000);
                }
            }
            DateTime mtEnd = DateTime.Now;
            System.Diagnostics.Debug.WriteLine("{0} MainThread - END", mtEnd.ToString("MM/dd/yyyy hh:mm:ss.fff tt"));
        }

        static void WriteY()
        {
            DateTime wtStart = DateTime.Now;
            System.Diagnostics.Debug.WriteLine("{0} WorkerThread - START", wtStart.ToString("MM/dd/yyyy hh:mm:ss.fff tt"));

            System.Diagnostics.Debug.WriteLine("Worker Thread - Starts Here!");
            for (int i = 0; i < 250; i++)
            {
                Console.Write("Y");
                System.Diagnostics.Debug.WriteLine("Y");
                System.Diagnostics.Debug.WriteIf(i == 249, "Y is OVER");
                if (i == 100)
                {
                    System.Diagnostics.Debug.WriteLine("HIT - 100!!!");
                    //Thread.Sleep(500);
                }
            }

            DateTime wtEnd = DateTime.Now;
            System.Diagnostics.Debug.WriteLine("{0} WorkerThread - END", wtEnd.ToString("MM/dd/yyyy hh:mm:ss.fff tt"));
        }
    }
}

这是输出:

'SmartDeviceProject6.exe'(托管):加载 'C:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\Debugger\BCL\mscorlib.dll' 'SmartDeviceProject6.exe'(托管):加载 'c: \users\icreate\documents\visual studio 2008\projects\smartdeviceproject6\smartdeviceproject6\bin\debug\SmartDeviceProject6.exe',已加载符号。'SmartDeviceProject6.exe'(托管):已加载 'C:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\Debugger\BCL\System.dll' 12/06/2012 01:02:36.000 PM:{ 0} MainThread - 开始主线程 - 从这里开始!xxxxxxxxxxxxxxxxxxxxx XXXXXXXX xxxxxxxxxxxxxxxxxxxxx x主 - 睡眠XXXXXXX xxxxxxxxxxxxxxxxxxxxx XXXXXXXXXXXXXX xxxxxxxxxxxxxxxxxxxxx XXXXXXXXXXXXXX xxxxxxxxxxxxxxxxxxxxx XXXXXXXXXXXXXX xxxxxxxxxxxxxxxxxxxxx XXXXXXXXXXXXXX xxxxxxxxxxxxxxxxxxxxx XXXXXXXXXXXXXX xxxxxxxxxxxxxxxxx X是OVER12 / 06/2012 01:02:38.000 PM:{0} MainThread - END 0xf6b1b7d6已经与代码0(为0x0)退出该线程. 12/06/2012 01:02:38.000 PM:{0} WorkerThread - 启动工作线程 - 从这里开始!YYYYYYYYYYYYYYYYYYYY YYY YYYYYYYYYYYYYYYYYYYY YYYYYYYYYYYYYY YYYYYYYYYYYYYYYYYYYY YYYYYYYYYYYYYY YYYYYY 命中 - 100!YYYYYYYYYYYYYYYYYYYYY Y YYYYYYYYYYYYYYYYYYYYY YYYYYYYYYYYYYY YYYYYYYYYYYYYYYYYY YYYYYYYYYYYYYY YYYYYYYYYYYYYYYYYYYY YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY YY 已超过 12/06/2012 01:02:38.000 PM:{0} WorkerThread - 已结束线程代码为 0x30009。线程 0xd7be774a 以代码 0 (0x0) 退出。程序“[0xF7D3F6F6] SmartDeviceProject6.exe: Managed”已退出,代码为 0 (0x0)。

有两件事困扰我...

1)是没有明显的线程进行...所有的X都被打印出来,然后是所有的Y,如果我做一个睡眠我可以交错代码,但似乎没有多线程进行......

2)这些是几个非常简单的 for 循环,它们不应该花一秒钟的时间来运行。

有谁知道 WinMobile 6.1 是否以正确的方式支持线程?我应该使用不同的线程模型吗?我能做些什么来加快速度?

4

1 回答 1

3

您看到的“缓慢”与您的调试器连接有关。 Debug.Writeline是同步且缓慢的(Console.Writeline也不是那么快)。例如,在我面前的 PXA270 设备上,我删除了它们并在两个循环中计数到 2500(比您的测试大 10 倍)只需要大约 80 毫秒。即使写入文件对速度的影响也很小。

我确实看到了相同的“所有一个线程然后所有其他线程”,当我完全跑出没有屈服时,但我不能说我过于惊讶。两个线程具有相同的优先级,很可能是线程量子是原因 - 如果您运行更多迭代,您将达到量子限制并且调度程序将交换。我Thread.Sleep(0)在每个循环中都放了一个,这使输出更像您所期望的,并且运行到 2500 的时间仅增加到大约 180 毫秒(线程上下文切换是减速)。

    static void Main(string[] args)
    {
        Debug.WriteLine("Start");
        var writer = File.CreateText("\\test.txt");
        var start = Environment.TickCount;
        var are = new AutoResetEvent(false);

        var t = new Thread(delegate
            {
                for (int i = 0; i < 2500; i++)
                {
                    writer.Write(".");
                    Thread.Sleep(0);
                }
                // set an event signaling completion
                are.Set();
            });
        t.Start();

        for (int i = 0; i < 2500; i++)
        {
            writer.Write("+");
            Thread.Sleep(0);
        }
        var et = Environment.TickCount - start;
        Debug.WriteLine(string.Format("\r\nET: {0}ms", et));
        // wait for the thread to complete
        are.WaitOne();
        // this would also work
        // t.Join();
        writer.Close();

        using(var reader = File.OpenText("\\test.txt"))
        {
            var content = reader.ReadToEnd();
            Debug.WriteLine(content);
        }
    }
于 2012-12-06T16:23:19.980 回答