3)创建TripOptimizer和TripOptimizerImpl类。C++组件包含一个WinRT类“TripOptimizerComponent::TripOptimizer”,这个类衔接其他WinRT组件,“TripOptimizer”类只定义了与其他WinRT组件通信的方法,而具体实现细节由TripOptimizerImpl类来处理,选择这个模式是来更好的封装公共接口,并将其从具体实现细节中分离,代码如下。
//定义TripOptimizer类.这个类衔接应用和具体实现细节
public ref class TripOptimizer sealed
{
public:
TripOptimizer();
~TripOptimizer();
//作为一个异步过程优化出行
Windows::Foundation::IAsyncOperationWithProgress<
Windows::Foundation::Collections::IMap<
Platform::String^,
Windows::Foundation::Collections::IVector<Platform::String^>^>^,
Platform::String^>^ OptimizeTripAsync(
Windows::Foundation::Collections::IVector<Platform::String^>^ waypoints,
Platform::String^ travelMode,
Platform::String^ optimize,
Platform::String^ bingMapsKey,
double alpha, double beta, double rho,
unsigned long iterations, bool parallel);
private:
// 定义优化程序的具体实现细节
std::unique_ptr<Details::TripOptimizerImpl> m_impl;
};
TripOptimizer::OptimizeTripAsync方法是应用和C++组件通信的方式,TripOptimizer::OptimizeTripAsync方法启动计算优化出行路线的任务序列,而从这个方法传回的值,用于监视进行优化的任务的进度和完成情况,其同样可以用来取消操作。ripOptimizer::OptimizeTripAsync方法是依据TripOptimizerImpl类来执行操作的,有关代码如下。
// 将优化出行路线作为一个异步的过程
IAsyncOperationWithProgress<IMap<String^, IVector<String^>^>^, String^>^
TripOptimizer::OptimizeTripAsync(
IVector<String^>^ waypoints,
String^ travelMode,
String^ optimize,
String^ bingMapsKey,
double alpha, double beta, double rho,
unsigned long iterations, bool parallel)
{
return m_impl->OptimizeTripAsync(waypoints,travelMode, optimize, bingMapsKey,
alpha, beta, rho, iterations, parallel);
}
4)组件的工作流程。TripOptimizer::OptimizeTripAsync方法,启动一系列操作来计算优化路径,这个方法进行异步执行,使应用能够保持响应,此方法返回Windows::Foundation::IAsyncOperationWithProgress<TResult, TProgress>接口,而一个调用此方法的WinRT组件,可以使用这个对象得到返回值,如果有的话。这个接口也使得调用函数可以监视运行进度,接收出现的任何错误。
每个WinRT使用的语言(C++,JavaScript等等)都有自身创建异步操作的方式。在C++中,可以利用Concurrency::create_async函数,这个函数返回一个IAsyncAction,IAsyncActionWithProgress<TProgress>,IAsyncOperation<TResult>或是IAsyncOperationWithProgress<TResult, TProgress>对象,其返回类型取决于传给它的函数对象的签名。比如,由于TripOptimizerImpl::OptimizeTripAsync方法将一个Concurrency::progress_reporter对象作为其参数并返回一个非空值,create_async返回IAsyncOperationWithProgress<TResult, TProgress>接口;如果这个方法返回为空,create_async将会返回IAsyncActionWithProgress<TProgress>接口,下面的代码演示了TripOptimizerImpl::OptimizeTripAsync方法。
//异步操作优化出行路径
IAsyncOperationWithProgress<IMap<String^, IVector<String^>^>^, String^>^
TripOptimizerImpl::OptimizeTripAsync(
IVector<String^>^ waypoints,
String^ travelMode,
String^ optimize,
String^ bingMapsKey,
double alpha, double beta, double rho,
unsigned long iterations, bool parallel)
{
// 将输入拷贝到一个OptimizeTripParams结构体
auto params = make_shared<OptimizeTripParams>();
for_each(begin(waypoints), end(waypoints), [params](String^ waypoint) {
params->Waypoints.push_back(waypoint->Data());
});
params->TravelMode = wstring(travelMode->Data());
params->Optimize = wstring(optimize->Data());
params->BingMapsKey = UriEncode(bingMapsKey->Data());
params->Alpha = alpha;
params->Beta = beta;
params->Rho = rho;
params->Iterations = iterations;
params->Parallel = parallel;
// 执行异步操作
return create_async([this, params](
progress_reporter<String^> reporter, cancellation_token cancellationToken)
{
// 为取消创建一个链接的资源
// 这样使得调用函数(通过返回的IAsyncOperationWithProgress对象)和这个类来设置同样的取消标记。
m_cancellationTokenSource =
cancellation_token_source::create_linked_source(cancellationToken);
// 执行优化操作
return OptimizeTrip(params, cancellationToken, reporter)
.then([this](task<IMap<String^, IVector<String^>^>^> previousTask) -> IMap<String^, IVector<String^>^>^
{
try {
return previousTask.get();
}
catch (task_canceled&) {
return nullptr;
}
}, cancellationToken);
});
}
progress_reporter对象与调用函数进行进度信息的通信,cancellation_token对象使组件响应撤销请求(下面的内容会讲到对撤销的处理)。
提供给TripOptimizer::OptimizeTripAsync中的create_async的功能函数返回一个“task”对象,而返回的可以是一个值,T类型,一个任务,或是create_async中的task<T>。返回task<T>可以使我们不用只得等待后台任务的运行结果,而是使运行时在运行结果出来的时候,获取结果并将其传递给调用函数。
TripOptimizer.cpp文件定义了task_from_result辅助函数,此函数返回一个连同所提供结果的“task”对象,在写一个返回“task”的函数时,使用这个函数会很有帮助,相关代码如下。
// 连同所提供结果创建一个任务
template <typename Result>
task<Result> task_from_result(Result result)
{
return task<Result>([result]() -> Result { return result; });
}
下图说明了当一个外部组件调用TripOptimizer::OptimizeTripAsync,启动优化操作时,引发的操作流程。