Multithreaded raster subset

本文介绍如何利用多线程架构与ArcObjects进行遥感影像处理,具体探讨了使用线程池、传递任务信息、线程同步及更新用户界面等关键技术点。

学习总结:

PurposeThis sample demonstrates using a multithreaded architecture together with ArcObjects to break a lengthy operation (here subsetting a raster layer), into multiple threads so that each thread performs part of the work. The entire task runs in the application background, leaving the application free to perform other tasks.

This sample follows the programming pattern of the 'Threads in Isolation' model, which means that cross-thread communication is reduced to an absolute minimum and is done with only simple types.
学会的只是点:
The issues covered by this sample are:

1 使用背景线程

2 执行线程池任务

3 传递任务信息到线程池

4 线程同步

5 等待多线程完成任务

6 通过多线程方式更新应用程序用户界面同时保持用户响应。
1. Spawning a background thread.

2. Working with ThreadPool tasks.
3. Passing task information onto a ThreadPool task.
4. Thread synchronization.
5. Waiting for multiple threads to finish their tasks.
6. Updating the application UI from multiple threads while keeping it responsive.

 

2 执行线程池任务

3 传递任务信息到线程池

 

Thread pooling enables you to use threads more efficiently by providing your application with a pool of worker threads that are managed by the system. The advantage of using a thread pool over creating a new thread for each task is that thread creation and destruction overhead is negated, which may result in better performance and better system stability.

 

Using ThreadPool tasks is highly efficient for operations that repeat themselves: handling client requests, listening on variable COM ports, subsetting multiple raster bands, and so on.

 建议使用的情况

1、 处理客服的请求

2、 监听各种com端口

3、 多线程遥感波段

 

When using a ThreadPool, there are a few things to keep in mind:

 

 

使用时注意的问题:

1、 所有的或者数据需要去执行多线程任务都必须传入自定义的类或结果到线程池。你该使用线程基于线程孤立模型去确保所有的数据都是简单的数据类型或者托管类型。

2、 你能够像控制别的线程一样控制线程池线程。如休眠 等

3、 当其进入队列是就没有方法取消其执行。

  • ThreadPools have an added advantage over the thread class. Not only do they allow you to create a thread, but they also let you pass an object associated with the thread to the thread delegate. This means that any information or data required to perform the ThreadPool task should be passed into that ThreadPool task through a user-defined class or structure. You should use the Threads in Isolation model to make sure all data is in the form of simple or managed types.
  • You can monitor ThreadPool tasks the same way as any other thread. This includes waiting for multiple threads to finish their tasks, setting a specific thread to sleep, and resuming a waiting task.
  • There is no way to cancel a work item after it has been queued.

 

The following example, an except from the Multithreaded Raster Subset sample, demonstrates using ThreadPool tasks to subset a RasterDataset, using a different task to subset each raster band.

 

 

4 线程同步

In many cases, you will have to synchronize the execution of concurrently running threads 并发线程(both regular threads and ThreadPool tasks). Normally you will have to wait for one or more threads to finish their tasks, signal a waiting thread to resume its task when a certain condition is met, test whether a given thread is alive and running, change a thread priority, or give some other indication.

 通常,你有可能不得不等待一个或多个线程来结束他们的任务,或在等待直到某些条件下才能执行某任务,或测试指定线程是否存活,或者运行,或改变线程优先级别,或者给于其某些其他的命令。

In .NET, there are several ways to manage the execution of running threads. The main classes available to help thread management are as follows:

 

如上任务的完成可以借助下面的方法或类:

1、 System.Threading.Thread  可以用来产生创建线程,改变优先级别,获取状态等。

2、 System.Threading.WaitHandle 定义一个发送机制去指示使用还是释放一个唯一访问的共享资源。

注意:调用WaitHandle.WaitAll()方法必须在多线程单元下,使用如线程池任务等类型的多线程同步任务,你首先必须调用工作线程来轮流执行工作线程任务。这样是运行程序的主线程是一个单线程运行平台。(不解)

 

3、 System.Threading.Monitor 类似与System.Threading.WaitHandle,这个类提供同步类对象的机制。

4、 System.Threading.AutoResetEvent and System.Threading.ManualResetEvent被用来通知等待线程:某个线程已经引发,容许线程通过一定的规则通信了。

 

  • System.Threading.Thread¾Used to create and control threads, change priority, and get status.
  • System.Threading.WaitHandle¾Defines a signaling mechanism to indicate taking or releasing exclusive access to a shared resource, allowing you to restrict access to a block of code.
    • Calling the WaitHandle.WaitAll() method must be done from a multithreaded apartment (MTA) thread. To launch multiple synchronized tasks such as ThreadPool tasks, you first have to launch a worker thread that in turn will generate the ThreadPool tasks. This keeps the application's main thread a single-threaded apartment (STA) thread.
  • System.Threading.Monitor¾Similar to System.Threading.WaitHandle, this class provides a mechanism that synchronizes access to objects.
  • System.Threading.AutoResetEvent and System.Threading.ManualResetEvent¾Used to notify waiting threads that an event has occurred, allowing threads to communicate with each other by signaling.

 在这个例子中。使用了ManualResetEventWaitHandle类来等待多线程去结束其任务,另外,描叙了使用AutoResetEvent类去阻碍当前线程去访问一个代码快,同时通知下一个可用线程当目前的任务已经完成时。

 

The following example, also in the Multithreaded Raster Subset sample, extends what was covered in the previous section. It uses the ManualResetEvent and the WaitHandle classes to wait for multiple threads to finish their tasks. In addition, it demonstrates using the AutoResetEvent class to block running threads from accessing a block of code and to signal the next available thread when the current thread had completed its task.

 

 

C#]

/// <summary>

/// Class used to pass the task information onto the working thread.

/// </summary>

public class TaskInfo

 

 

{

//Signal the main thread that the thread has finished its task.

//通知主线程,当某个线程完成了其任务

 private ManualResetEvent m_doneEvent;

...

public TaskInfo(int BandID, ManualResetEvent doneEvent)

{

        m_bandID = BandID;

        m_doneEvent = doneEvent;

}

...

public ManualResetEvent DoneEvent

{

get { return m_doneEvent;  }

set { m_doneEvent = value; }

}

}

 

//Block access to the shared resource (raster dataset).

private static AutoResetEvent m_autoEvent = new AutoResetEvent(false);

 

...

public override void OnMouseDown(int Button, int Shift, int X, int Y)

{

   ...

//Run the subset thread that will use the ThreadPool tasking.

   Thread t = new Thread(new ThreadStart(SubsetProc));

t.Start();

}

 

/// <summary>

/// Main subset method.

/// </summary>

private void SubsetProc()

{

...

//Create ManualResetEvent to notify the main threads that

//all ThreadPool threads are done with their tasks.

ManualResetEvent[] doneEvents = new ManualResetEvent[m_intBandCount];

 

//Create a threadpool task for each band of the input raster.

//Each task will subset a different raster band.

   //All information required for subsetting the raster band will be passed to the threadpool task by the user-defined class TaskInfo.

for (int i = 0; i < m_intBandCount; i++)

{

//Create the ManualResetEvent field for the task to

      // signal the waiting thread that the task had been completed.

doneEvents[i] = new ManualResetEvent(false);

 

TaskInfo ti = new TaskInfo(i, doneEvents[i]);

...

//Queue a method for execution, and specify the object containing the data to be used by the method (TaskInfo).

      //The method will execute when the thread pool thread becomes available.

ThreadPool.QueueUserWorkItem(new WaitCallback(SubsetRasterBand), (object)ti);

}

 

//Set the state of the event to signaled to allow one or more of the waiting threads to proceed.

m_autoEvent.Set();        

}

 

/// <summary>

/// ThreadPool subset task method

/// </summary>

/// <param name="state"></param>

private void SubsetRasterBand(object state)

{

// The state object must be cast to the correct type, because the

// signature of the WaitOrTimerCallback delegate specifies type

// Object.

TaskInfo ti = (TaskInfo)state;

...

 

//Lock all other threads to get exclusive access.

m_autoEvent.WaitOne();

 

//Insert code containing your threading logic here.

 

//Signal the next available thread to get write access.

m_autoEvent.Set();

 

//Signal the main thread that the thread has finished its task.

ti.DoneEvent.Set();

}

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值