ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-Threading(线程处理)
1.A,示例(Sample) 返回顶部

“线程处理”示例

本示例演示了下面的线程处理技术。有关更多信息,请参见线程处理(C# 编程指南) 。

  • 创建、启动和终止线程

  • 使用线程池

  • 线程同步和互交

安全说明

提供此代码示例是为了阐释一个概念,它并不代表最安全的编码实践,因此不应在应用程序或网站中使用此代码示例。对于因将此代码示例用于其他用途而出现的偶然或必然的损害,Microsoft 不承担任何责任。

在 Visual Studio 中生成并运行“线程处理”示例

  1. 在“解决方案资源管理器”中,右击“ThreadStartStop”项目并单击“设为启动项目”。

  2. 在“调试”菜单上,单击“开始执行(不调试)”。

  3. 对于 ThreadPool 和 ThreadSync,分别重复上述步骤。

从命令行生成并运行“线程”示例

  1. 使用“更改目录”命令转到“Threads”目录。

  2. 键入以下命令:

    cd ThreadStartStop
    csc ThreadStartStop.cs
    ThreadStartStop
  3. 键入以下命令:

    cd ..\ThreadPool
    csc ThreadPool.cs
    ThreadPool
  4. 键入以下命令:

    cd ..\ThreadSync
    csc ThreadSync.cs
    ThreadSync
1.B,ThreadStartStop 示例代码(Sample Code)返回顶部

1.B.1, ThreadStartStop.cs

// 版权所有(C) Microsoft Corporation。保留所有权利。
// 此代码的发布遵从
// Microsoft 公共许可(MS-PL,http://opensource.org/licenses/ms-pl.html)的条款。
//
//版权所有(C) Microsoft Corporation。保留所有权利。 using System;
using System.Threading; public class Worker
{
// 启动线程时调用此方法。
public void DoWork()
{
while (!_shouldStop)
{
Console.WriteLine("worker thread: working...");
}
Console.WriteLine("worker thread: terminating gracefully.");
}
public void RequestStop()
{
_shouldStop = true;
}
// Volatile 用于向编译器提示此数据
// 成员将由多个线程访问。
private volatile bool _shouldStop;
} public class WorkerThreadExample
{
static void Main()
{
// 创建线程对象。这不会启动该线程。
Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork); // 启动辅助线程。
workerThread.Start();
Console.WriteLine("main thread: Starting worker thread..."); // 循环直至辅助线程激活。
while (!workerThread.IsAlive); // 为主线程设置 1 毫秒的休眠,
// 以使辅助线程完成某项工作。
Thread.Sleep(); // 请求辅助线程自行停止:
workerObject.RequestStop(); // 使用 Join 方法阻塞当前线程,
// 直至对象的线程终止。
workerThread.Join();
Console.WriteLine("main thread: Worker thread has terminated.");
}
}

1.B.2,

1.B.EXE,

main thread: Starting worker thread...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: working...
worker thread: terminating gracefully.
main thread: Worker thread has terminated.
请按任意键继续. . .

1.B

1.B,ThreadPool 示例代码2(Sample Code)返回顶部

1.B.1, ThreadPool.cs

// 版权所有(C) Microsoft Corporation。保留所有权利。
// 此代码的发布遵从
// Microsoft 公共许可(MS-PL,http://opensource.org/licenses/ms-pl.html)的条款。
//
//版权所有(C) Microsoft Corporation。保留所有权利。 using System;
using System.Threading; // Fibonacci 类为使用辅助
// 线程执行长时间的 Fibonacci(N) 计算提供了一个接口。
// N 是为 Fibonacci 构造函数提供的,此外还提供了
// 操作完成时对象发出的事件信号。
// 然后,可以使用 FibOfN 属性来检索结果。
public class Fibonacci
{
public Fibonacci(int n, ManualResetEvent doneEvent)
{
_n = n;
_doneEvent = doneEvent;
} // 供线程池使用的包装方法。
public void ThreadPoolCallback(Object threadContext)
{
int threadIndex = (int)threadContext;
Console.WriteLine("thread {0} started...", threadIndex);
_fibOfN = Calculate(_n);
Console.WriteLine("thread {0} result calculated...", threadIndex);
_doneEvent.Set();
} // 计算第 N 个斐波纳契数的递归方法。
public int Calculate(int n)
{
if (n <= )
{
return n;
}
else
{
return Calculate(n - ) + Calculate(n - );
}
} public int N { get { return _n; } }
private int _n; public int FibOfN { get { return _fibOfN; } }
private int _fibOfN; ManualResetEvent _doneEvent;
} public class ThreadPoolExample
{
static void Main()
{
const int FibonacciCalculations = ; // 每个 Fibonacci 对象使用一个事件
ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations];
Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations];
Random r = new Random(); // 使用 ThreadPool 配置和启动线程:
Console.WriteLine("launching {0} tasks...", FibonacciCalculations);
for (int i = ; i < FibonacciCalculations; i++)
{
doneEvents[i] = new ManualResetEvent(false);
Fibonacci f = new Fibonacci(r.Next(,), doneEvents[i]);
fibArray[i] = f;
ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);
} // 等待池中的所有线程执行计算...
WaitHandle.WaitAll(doneEvents);
Console.WriteLine("Calculations complete."); // 显示结果...
for (int i= ; i<FibonacciCalculations; i++)
{
Fibonacci f = fibArray[i];
Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);
}
}
}

1.B.2,

1.B.EXE,

launching  tasks...
thread started...
thread started...
thread result calculated...
thread started...
thread result calculated...
thread started...
thread result calculated...
thread started...
thread result calculated...
thread started...
thread result calculated...
thread started...
thread result calculated...
thread started...
thread result calculated...
thread started...
thread result calculated...
thread started...
thread result calculated...
thread result calculated...
Calculations complete.
Fibonacci() =
Fibonacci() =
Fibonacci() =
Fibonacci() =
Fibonacci() =
Fibonacci() =
Fibonacci() =
Fibonacci() =
Fibonacci() =
Fibonacci() =
请按任意键继续. . .

1.B,

1.B,ThreadSync 示例代码3(Sample Code)返回顶部

1.B.1, ThreadSync.cs

// 版权所有(C) Microsoft Corporation。保留所有权利。
// 此代码的发布遵从
// Microsoft 公共许可(MS-PL,http://opensource.org/licenses/ms-pl.html)的条款。
//
//版权所有(C) Microsoft Corporation。保留所有权利。 using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic; // 将线程同步事件封装在此类中,
// 以便于将这些事件传递给 Consumer 和
// Producer 类。
public class SyncEvents
{
public SyncEvents()
{
// AutoResetEvent 用于“新项”事件,因为
// 我们希望每当使用者线程响应此事件时,
// 此事件就会自动重置。
_newItemEvent = new AutoResetEvent(false); // ManualResetEvent 用于“退出”事件,因为
// 我们希望发出此事件的信号时有多个线程响应。
// 如果使用 AutoResetEvent,事件
// 对象将在单个线程作出响应之后恢复为
// 未发信号的状态,而其他线程将
// 无法终止。
_exitThreadEvent = new ManualResetEvent(false); // 这两个事件也放在一个 WaitHandle 数组中,以便
// 使用者线程可以使用 WaitAny 方法
// 阻塞这两个事件。
_eventArray = new WaitHandle[];
_eventArray[] = _newItemEvent;
_eventArray[] = _exitThreadEvent;
} // 公共属性允许对事件进行安全访问。
public EventWaitHandle ExitThreadEvent
{
get { return _exitThreadEvent; }
}
public EventWaitHandle NewItemEvent
{
get { return _newItemEvent; }
}
public WaitHandle[] EventArray
{
get { return _eventArray; }
} private EventWaitHandle _newItemEvent;
private EventWaitHandle _exitThreadEvent;
private WaitHandle[] _eventArray;
} // Producer 类(使用一个辅助线程)
// 将项异步添加到队列中,共添加 20 个项。
public class Producer
{
public Producer(Queue<int> q, SyncEvents e)
{
_queue = q;
_syncEvents = e;
}
public void ThreadRun()
{
int count = ;
Random r = new Random();
while (!_syncEvents.ExitThreadEvent.WaitOne(, false))
{
lock (((ICollection)_queue).SyncRoot)
{
while (_queue.Count < )
{
_queue.Enqueue(r.Next(, ));
_syncEvents.NewItemEvent.Set();
count++;
}
}
}
Console.WriteLine("Producer thread: produced {0} items", count);
}
private Queue<int> _queue;
private SyncEvents _syncEvents;
} // Consumer 类通过自己的辅助线程使用队列
// 中的项。Producer 类使用 NewItemEvent
// 将新项通知 Consumer 类。
public class Consumer
{
public Consumer(Queue<int> q, SyncEvents e)
{
_queue = q;
_syncEvents = e;
}
public void ThreadRun()
{
int count = ;
while (WaitHandle.WaitAny(_syncEvents.EventArray) != )
{
lock (((ICollection)_queue).SyncRoot)
{
int item = _queue.Dequeue();
}
count++;
}
Console.WriteLine("Consumer Thread: consumed {0} items", count);
}
private Queue<int> _queue;
private SyncEvents _syncEvents;
} public class ThreadSyncSample
{
private static void ShowQueueContents(Queue<int> q)
{
// 对集合进行枚举本来就不是线程安全的,
// 因此在整个枚举过程中锁定集合以防止
// 使用者和制造者线程修改内容
// 是绝对必要的。(此方法仅由
// 主线程调用。)
lock (((ICollection)q).SyncRoot)
{
foreach (int i in q)
{
Console.Write("{0} ", i);
}
}
Console.WriteLine();
} static void Main()
{
// 配置结构,该结构包含线程同步
// 所需的事件信息。
SyncEvents syncEvents = new SyncEvents(); // 泛型队列集合用于存储要制造和使用的
// 项。此例中使用的是“int”。
Queue<int> queue = new Queue<int>(); // 创建对象,一个用于制造项,一个用于
// 使用项。将队列和线程同步事件传递给
// 这两个对象。
Console.WriteLine("Configuring worker threads...");
Producer producer = new Producer(queue, syncEvents);
Consumer consumer = new Consumer(queue, syncEvents); // 为制造者对象和使用者对象创建线程
// 对象。此步骤并不创建或启动
// 实际线程。
Thread producerThread = new Thread(producer.ThreadRun);
Thread consumerThread = new Thread(consumer.ThreadRun); // 创建和启动两个线程。
Console.WriteLine("Launching producer and consumer threads...");
producerThread.Start();
consumerThread.Start(); // 为制造者线程和使用者线程设置 10 秒的运行时间。
// 使用主线程(执行此方法的线程)
// 每隔 2.5 秒显示一次队列内容。
for (int i = ; i < ; i++)
{
Thread.Sleep();
ShowQueueContents(queue);
} // 向使用者线程和制造者线程发出终止信号。
// 这两个线程都会响应,由于 ExitThreadEvent 是
// 手动重置的事件,因此除非显式重置,否则将保持“设置”。
Console.WriteLine("Signaling threads to terminate...");
syncEvents.ExitThreadEvent.Set(); // 使用 Join 阻塞主线程,首先阻塞到制造者线程
// 终止,然后阻塞到使用者线程终止。
Console.WriteLine("main thread waiting for threads to finish...");
producerThread.Join();
consumerThread.Join();
}
}

1.B.2,

1.B.EXE,

Configuring worker threads...
Launching producer and consumer threads... Signaling threads to terminate...
main thread waiting for threads to finish...
Producer thread: produced items
Consumer Thread: consumed items
请按任意键继续. . .

1.B,

1.C,下载地址(Free Download)返回顶部
作者:ylbtech
出处:http://ylbtech.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

ylbtech-LanguageSamples-Threading(线程处理)的更多相关文章

  1. python并发编程之threading线程(一)

    进程是系统进行资源分配最小单元,线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.进程在执行过程中拥有独立的内存单元,而多个线程共享内存等资源. 系列文章 py ...

  2. pythonl练习笔记——threading线程中的事件Event

    1 事件Event 使用方法:e = threading.Event() Event对象主要用于线程间通信,确切地说是用于主线程控制其他线程的执行. Event事件提供了三个方法:wait等待.cle ...

  3. 多进程 multiprocessing 多线程Threading 线程池和进程池concurrent.futures

    multiprocessing.procsess 定义一个函数 def func():pass 在if __name__=="__main__":中实例化 p = process( ...

  4. Python Threading 线程/互斥锁/死锁/GIL锁

    导入线程包 import threading 准备函数线程,传参数 t1 = threading.Thread(target=func,args=(args,)) 类继承线程,创建线程对象 class ...

  5. threading线程中的方法(27-11)

    t1.start() # 执行线程 t1.join() # 阻塞 t1.setDaemon(True) #守护线程 threading.current_thread() # 查看执行的是哪一个线程 t ...

  6. threading线程例子 (27-08)

    利用阻塞的时间空闲去执行另一个子线程 import threading from time import ctime, sleep def music(func): for i in range(2) ...

  7. import threading线程进程

    cpu在执行一个子线程的时候遇到sleep就会利用这段停顿时间去执行另一个子线程.两个子线程谁先跳出sleep就执行谁. import threadingimport time start = tim ...

  8. Python学习笔记--threading线程

    通过线程来实现多任务并发.提高性能.先看看例子. #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2020-03-02 21:10:39 ...

  9. Python线程的用法 函数式线程_thread和threading 样例

    函数式线程写起来比较简单,但是功能没有threading那么高级,先来个函数式编程样例: #!/usr/bin/python #coding: utf-8 #————————————————————— ...

  10. C# - 多线程 之 进程与线程

    并行~并发 并发 Concurrency,逻辑上的同时发生,一个处理器(在不同时刻或者说在同一时间间隔内)"同时"处理多个任务.宏观上是并发的,微观上是按排队等待.唤醒.执行的步骤 ...

随机推荐

  1. java的nio之:java的nio系列教程之概述

    一:java的nio的核心组件?Java NIO 由以下几个核心部分组成: ==>Channels ==>Buffers ==>Selectors 虽然Java NIO 中除此之外还 ...

  2. Microservice Orleans

    https://azure.microsoft.com/en-us/blog/containers-docker-windows-and-trends/ https://channel9.msdn.c ...

  3. @include与jsp:include的区别

    1.可以使用一个JSP指令或者一个标准行为,在JSP页面中引入其他的页面片段. 2. include指令:在翻译阶段(将JSP页面转换成servlet的阶段),JSP的include指令会读入指定的页 ...

  4. CSQuery 简单测试

    1. 使用环境 vs2010  ,csquery 2. 测试的内容 学习了解csquery 3. 代码 添加csquery 的就不用写了 测试的例子是获取我的博客的信息,使用webbrowser 控件 ...

  5. ExtJs学习笔记之学习小结LoginDemo

    ExtJs学习小结LoginDemo 1.示例:(登录界面) <!DOCTYPE html> <html> <head> <meta charset=&quo ...

  6. jquery技巧总结

    jquery技巧总结一.简介 1.1.概述随着WEB2.0及ajax思想在互联网上的快速发展传播,陆续出现了一些优秀的Js框架,其中比较著名的有Prototype.YUI.jQuery.mootool ...

  7. 使用匿名委托,Lambda简化多线程代码

    使用匿名委托,Lambda简化多线程代码   .net中的线程也接触不少了.在多线程中最常见的应用莫过于有一个耗时的操作需要放到线程中去操作,而在这个线程中我们需要更新UI,这个时候就要创建一个委托了 ...

  8. nova分析(3)—— nova-api

    nova-api是nova对外提供Restful API的服务,Horizon.novaclient等均通过该api与nova进行通信. nova其实对外提供了多个api服务,包括下面这些服务: no ...

  9. 【转】关于 hashCode() 你需要了解的 3 件事

    在 Java 中,每一个对象都有一个容易理解但是仍然有时候被遗忘或者被误用的 hashCode 方法.这里有3件事情要时刻牢记以避免常见的陷阱. 一个对象的哈希码允许算法和数据结构将对象放入隔间,就象 ...

  10. VB中判断空的几种方法,Null, Missing, Empty, Nothing, vbNullString区别

    vb6中存在几个虚幻的值:Null.Missing.Empty.Nothing.vbNullString.除了最后一个之外,每一个值都不能直接用“a=值”来判断.下面分别解释一下这几个值的含义. 1. ...