F1:Dispatcher 类:提供用于管理线程工作项队列的服务。

  1. Dispatcher 可为特定线程维护其按优先顺序排列的工作项队列。
  2. 当在线程中创建了 Dispatcher 时,它将成为可与该线程关联的唯一 Dispatcher,即使 Dispatcher 已经关闭。如果 Dispatcher 已经关闭,它将无法重新启动。??
  3. 在 WPF 中, DispatcherObject 只能通过与它关联的 Dispatcher 进行访问。 例如,后台线程不能更新与 UI 线程中的 Dispatcher 关联的 Button 内容。为了使该后台线程能够访问 Button 的 Content 属性,该后台线程必须将此工作委托给与该 UI 线程关联的 Dispatcher。使用 Invoke 或 BeginInvoke 来完成此操作。 Invoke 是同步操作,而 BeginInvoke 是异步操作。该操作将按指定的 DispatcherPriority 添加到 Dispatcher 的队列中。
  4. 如果对某个已关闭的 Dispatcher 调用 BeginInvoke,则返回的 DispatcherOperation 的状态属性将设置为 Aborted。
  5. 派生自 DispatcherObject 的对象具有线程关联。派生自 Freezable 的对象在冻结时是自由线程的。除 DisableProcessing 以外,Dispatcher 上的所有方法均是自由线程的。

F2:DispatcherObject 类:与 Dispatcher 关联的对象。其唯一个属性为Dispatcher.

  1. 只有在其上创建 Dispatcher 的线程才可以直接访问 DispatcherObject。若要从不同于在其上创建 DispatcherObject 的线程的某个线程访问 DispatcherObject,请对与 DispatcherObject 关联的 Dispatcher 调用 Invoke 或 BeginInvoke。
  2. 需要强制线程安全的 DispatcherObject 的子类可以通过对所有公共方法调用 VerifyAccess 来强制线程安全。这样可以保证调用线程是在其上创建 DispatcherObject 的线程。
  3. 无法单独对 DispatcherObject 进行实例化;也就是说,所有构造函数都是受保护的。
  4. 派生自 DispatcherObject 的对象具有线程关联。派生自 Freezable 的对象在冻结时是自由线程的。

F3:Thread 类:创建和控制线程,设置其优先级并获取其状态。

  1. 一个进程可以创建一个或多个线程,以执行与进程关联的程序代码的一部分。 使用 ThreadStart 委派或 ParameterizedThreadStart 委托指定的其他线程执行的程序代码。 ParameterizedThreadStart 委托允许您将数据传递给线程的过程。
  2. 对于其存在状态的持续时间,线程始终为一个或多个定义的状态中 ThreadState。 计划的优先级别,如中定义的 ThreadPriority, ,可以请求对某个主题,但不是能保证遵循由操作系统。

F4:ApartmentState 枚举:指定 Thread 的单元状态。

  1. MTA Thread 将创建并进入一个多线程单元。
  2. STA Thread 将创建并进入一个单线程单元。
  3. Unknown 尚未设置 ApartmentState 属性。
  4. 单元是进程内部具有相同线程访问要求的对象的逻辑容器。 同一单元中的所有对象都可以接收从该单元中的任何线程发出的调用。 .NET Framework 不使用单元,托管对象自己负责以线程安全的方式使用所有共享资源。

F5:Thread.IsBackground 属性:线程是后台线程或一个前台线程。 后台线程均与前台线程相同的,只不过后台线程不会阻止进程终止。 一旦属于某个进程的所有前台线程都已终止,公共语言运行时将结束该进程。任何剩余的后台线程将停止,其并不会完成剩余工作。

比如如下:当前台线程完成时到10时,后台线程也只完成到10,并不会执行其最后一句输出:

clipboard.png

class Test
{
    static void Main()
    {
        BackgroundTest shortTest = new BackgroundTest(10);
        Thread foregroundThread = 
            new Thread(new ThreadStart(shortTest.RunLoop));
        foregroundThread.Name = "ForegroundThread";

        BackgroundTest longTest = new BackgroundTest(50);
        Thread backgroundThread = 
            new Thread(new ThreadStart(longTest.RunLoop));
        backgroundThread.Name = "BackgroundThread";
        backgroundThread.IsBackground = true;

        foregroundThread.Start();
        backgroundThread.Start();
    }
}

class BackgroundTest
{
    int maxIterations;

    public BackgroundTest(int maxIterations)
    {
        this.maxIterations = maxIterations;
    }

    public void RunLoop()
    {
        String threadName = Thread.CurrentThread.Name;

        for(int i = 0; i < maxIterations; i++)
        {
            Console.WriteLine("{0} count: {1}", 
                threadName, i.ToString());
            Thread.Sleep(250);
        }
        Console.WriteLine("{0} finished counting.", threadName);
    }
}

F6:Dispatcher.Run 静态方法:主执行帧将继续执行,直至 Dispatcher 关闭。

  1. Dispatcher 将通过循环处理事件队列。该循环也称为“帧”。通常,初始循环由应用程序通过调用 Run 启动。
  2. 保持Dispatcher上的线程继续,暂时不关闭线程。

F7:Application.Startup 事件:在调用 Application 对象的 Run 方法时发生。包括:

  1. 处理命令行参数。
  2. 打开主窗口。
  3. 初始化应用程序范围的资源。
  4. 初始化应用程序范围的属性。

扩展:

  1. 可以使用 XAML 以声明方式指定主窗口和应用程序范围的资源(分别为 StartupUri 和 Resources)。 但是,应用程序的资源或主窗口有时只能在运行时以编程方式确定。 此外,只能以编程的方式使用应用程序范围的属性和命令行参数。
  2. 通过处理 Startup 事件可以执行编程初始化,包括以下这些:

    1. 获取并处理命令行参数,这些参数可从传递给 Startup 事件处理程序的 StartupEventArgs 类的 Args 属性获取。
    2. 使用 Resources 属性初始化应用程序范围的资源。
    3. 使用 Properties 属性初始化应用程序范围内的属性。
    4. 实例化并显示一个(或多个)窗口。
  3. 命令行参数还可以通过调用 Environment 对象的静态 GetCommandLineArgs 方法来获取。 但是,执行 GetCommandLineArgs 这需要完全授信。
  4. 如果使用 XAML 设置 StartupUri,则在处理 Startup 事件之前,不能从 Application 对象的 MainWindow 属性或 Windows 属性访问创建的主窗口。 如果需要在启动期间访问主窗口,则需要通过 Startup 事件处理程序手动创建新的窗口对象。
  5. 如果应用程序使用 CredentialPolicy 指定凭据策略,则需要在引发 Startup 之后设置 CredentialPolicy;否则 WPF 会在已引发 Startup 事件之后直接将其设置为默认内部策略。
  6. 传递给 Startup 事件处理程序的命令行实参与传递给 XAML 浏览器应用程序 (XBAP) 的 URL 查询字符串形参是不相同的。

F8:WindowsFormsApplicationBase 类:提供与当前应用程序相关的属性、方法和事件。

clipboard.png

  1. My.Application 对象由以下类组成:

    1. ApplicationBase 提供在所有项目中可用的成员。
    2. WindowsFormsApplicationBase 提供在 Windows 窗体应用程序可用的成员。
    3. ConsoleApplicationBase 提供在控制台应用程序可用的成员。
  2. My.Application 对象公开的属性返回只与当前应用程序或 DLL 关联的数据。 无法利用 My.Application 更改任何系统级别的信息。

F9:Application.LoadComponent 方法:加载位于指定统一资源标识符 (URI) 处的 XAML 文件。

  1. XAML 文件可以是应用程序代码文件(配置为 Microsoft Build Engine (MSBuild) 页面项),也可以是应用程序数据文件(资源文件、内容文件或源站点文件;
  2. 静态成员 LoadComponent(Uri) 必须将返回值显式转换为与 XAML 文件的根元素相同的类型。

F10:Application.DispatcherUnhandledException 事件:在异常由应用程序引发但未进行处理时发生。

  1. 默认情况下,WPF 捕获未经处理的异常,通过一个对话框通知用户发生了异常(用户可以从该对话框报告异常),并且自动关闭应用程序。
  2. 但是,如果应用程序需要从一个集中位置执行自定义的未经处理的异常处理,则应处理 DispatcherUnhandledException。
  3. 对于在主 UI 线程上运行的代码未处理的每个异常, Application 都将引发一个 DispatcherUnhandledException。
  4. 如果某个异常既未在后台 用户界面 (UI) 线程(自身具有 Dispatcher 的线程)上处理,也未在后台辅助线程(不具有 Dispatcher 的线程)上处理,则该异常不会转发到主 UI 线程。 因此不会引发 DispatcherUnhandledException。 在这些情况下,您将需要编写代码以执行以下操作:

    1. 在后台线程上处理异常。
    2. 将这些异常调度到主 UI 线程。
    3. 在主 UI 线程上再次引发这些异常而不进行处理,以便可以引发 DispatcherUnhandledException。
  5. 向 DispatcherUnhandledException 事件处理程序传递一个 DispatcherUnhandledExceptionEventArgs 参数,该参数包含与异常有关的上下文信息,这些信息包括:

    1. 异常 ( Exception)。
    2. 发出异常的 Dispatcher ( Dispatcher)。
  6. 可以使用这些信息确定异常是否可以恢复。 例如,可以恢复的异常可能是一个 FileNotFoundException,而不可恢复的异常可能是一个 StackOverflowException。
  7. 当您处理一个来自 DispatcherUnhandledException 的未经处理的异常,并且不希望 WPF 继续处理该异常时,需要将 Handled 属性设置为 true。

李志玮
22 声望34 粉丝

求索~~


引用和评论

0 条评论