Learning WCF Chapter1 Hosting a Service in IIS

How messages reach a service endpoint is a matter of protocols and hosting.
IIS can host services over HTTP protocol,the Windows Activation Service (WAS) can support others such as TCP and named pipes,
and self-hosting can support many protocols and includes several deployment options such as console or Windows Forms applications and Windows services. Selecting a hosting environment has nothing to do with service implementation,but everything to do with service deployment and overall system design.
This lab will show you how to host an existing service type as part of a web site hosted in IIS.
In the process, I’ll also be illustrating other extended concepts such as:
• The WCF Service web site template
• Message-based activation
• Additional metadata behavior settings
• Exporting service descriptions
• Consuming service description documents to generate client code
As always, after the lab I’ll describe some of these features in greater detail.
Lab: Creating an IIS Host and Browsing Metadata
For this lab,you will work with an existing solution that contains a completed service library and shell client application.
Using Visual Studio templates,you’ll create a new IIS web site project that contains a service and modify it to host a preexisting service.
To consume the service,you’ll generate a client proxy from static service documentation exported using SvcUtil.
Creating a WCF Service web site
The first thing to do is create a WCF-enabled web site using the WCF Service template,which is new to WCF.
When services are added to a web site,the supplied sample service is accompanied by a .svc file, the web server endpoint.
1. Open the startup solution for the lab,located at <YourLearningWCFPath>\Labs\Chapter1\IISHostedService\IISHostedService.sln.
This solution contains a copy of the HelloIndigo project from earlier labs and a shell client application.
2. You are going to create a new web site to host the service.
Go to Solution Explorer,right-click the solution node and select Add ➝ New Web Site.
Select the WCF Service template and make sure the location type for the new web site is HTTP (see Figure 1-25).
Set the location value to http://localhost/IISHostedService.
Note:
When Visual Studio creates a new HTTP web site,a virtual application is created in IIS pointing to a directory beneath
c:\inetpub\wwwroot (or wherever your Default Web Site is pointing).
In Figure 1-25,the path to the IISHostedService project might be c:\inetpub\wwwroot\IISHostedService.

Figure 1-25. Creating a new web site with the WCF Service template
3. The WCF Service template generates a new web site with a default service implementation.
You can delete the service implementation since you will be hosting an existing service.
Go to Solution Explorer and expand the App_Code folder for the web site (see Figure 1-26).
There you’ll see the files IService.cs and Service.cs.
Delete them from the project.

Figure 1-26. Solution Explorer view of a new web site based on the WCF Service template
4. Go to the web site project and add a reference to the HelloIndigo project,which contains the service you’re about to host.
5. You now can modify the web endpoint for the service so that it is associated with the correct service type.
Open Service.svc in the code window and modify the @ServiceHost directive to associate the web endpoint with the service type HelloIndigo.HelloIndigoService.
Remove the other attributes so that the end result looks as shown here:
<%@ ServiceHost Service="HelloIndigo.HelloIndigoService" %>
Note:
Now,when a request arrives to Service.svc,the service model will activate a new ServiceHost instance associated with the HelloIndigoService type.
6. The WCF Service template also generated configuration settings for the host,but these settings are based on the service supplied by the template.
You must modify these settings to reflect the correct service contract and service type.
Open the web.config file and find the <service> section.
Change the name attribute of the <service> section to HelloIndigo.HelloIndigoService
and change the contract attribute of the <endpoint> section to HelloIndigo.IHelloIndigoService.
While you’re at it,change the binding to basicHttpBinding instead of wsHttpBinding,
remove the identity settings for the endpoint,and remove the metadata endpoint.
The <service> section should look as shown here when you are done:
<services>
<service name="HelloIndigo.HelloIndigoService" behaviorConfiguration="ServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="" binding="basicHttpBinding" contract="HelloIndigo.IHelloIndigoService">
<!--
部署时,应删除或替换下列标识元素,以反映
用来运行所部署服务的标识。删除之后,WCF 将
自动推断相应标识。
-->
</endpoint>
</service>
</services>
Modify the service behavior to remove metadata exchange support for now.
The behavior should look as follows when you are done:
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
You now have a web site that will expose an endpoint to reach HelloIndigoService.
Before generating the client proxy, I’ll show you some useful metadata features.
Browsing service metadata
In this part of the lab,you’ll make changes to the configuration file so that metadata can be viewed in a browser.
In order to understand more about metadata you will manually configure some of the configuration settings removed in the previous section.
1. Before making any changes,test the web endpoint in a browser.
Go to Solution Explorer and right-click on the web site project node;
select “Set as Startup Project.”
Run the web site from within Visual Studio (F5).
This launches the service endpoint located at http://localhost/IISHostedService/Service.svc in a browser.
What you should see is a web page indicating that metadata publishing has been disabled for the service.
在浏览器中打开查看http://localhost/IISHostedService/Service.svc

有关发布元数据的详细信息,请参阅下列文档: http://go.microsoft.com/fwlink/?LinkId=65455。
2. Add metadata support to the service model configuration for the web site.
Open the web.config file and modify the previously generated service behavior to add the <serviceMetadata> behavior.
You will also add a metadata exchange endpoint for the service.
The changes are shown in bold in Example 1-14.
关键代码:
<service>中增加元数据的终结点 <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
<serviceBehaviors>中增加元数据的行为 <serviceMetadata/>
<system.serviceModel>
<services>
<service name="HelloIndigo.HelloIndigoService" behaviorConfiguration="ServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="" binding="basicHttpBinding" contract="HelloIndigo.IHelloIndigoService">
<!--
部署时,应删除或替换下列标识元素,以反映
用来运行所部署服务的标识。删除之后,WCF 将
自动推断相应标识。
--> </endpoint>
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceMetadata/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
3. Run the web site again (F5). This time you should see the service help page in the browser,providing some instructions for SvcUtil.
Leave the browser running and return to Visual Studio.

4. Without restarting the host,you’re going to make a change that enables HTTP GET access to the service metadata.
Open the web.config file and set httpGetEnabled to true for the <serviceMetadata> behavior:
<behavior name="returnFaults">
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceMetadata httpGetEnabled="true"/>
</behavior>
Save this change and return to the browser instance showing the service help page.
5. Refresh the browser (F5) to see what has changed. This time,you should observe the SvcUtil instruction has an active link with a ?wsdl suffix after the service endpoint (see Figure 1-27).

Figure 1-27. Browsing to the service help page with metadata browsing enabled
Click the link,and you’ll be taken to the WSDL document for the service (see Figure 1-28).

Figure 1-28. Browsing to the dynamically generated WSDL document
<?xml version="1.0" encoding="utf-8" ?>
- <wsdl:definitions name="HelloIndigoService" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:i0="http://www.thatindigogirl.com/samples/2006/06" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<wsdl:import namespace="http://www.thatindigogirl.com/samples/2006/06" location="http://lujuntao/IISHostedService/Service.svc?wsdl=wsdl0" />
<wsdl:types />
- <wsdl:binding name="BasicHttpBinding_IHelloIndigoService" type="i0:IHelloIndigoService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
- <wsdl:operation name="HelloIndigo">
<soap:operation soapAction="http://www.thatindigogirl.com/samples/2006/06/IHelloIndigoService/HelloIndigo" style="document" />
- <wsdl:input>
<soap:body use="literal" />
</wsdl:input>
- <wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
- <wsdl:service name="HelloIndigoService">
- <wsdl:port name="BasicHttpBinding_IHelloIndigoService" binding="tns:BasicHttpBinding_IHelloIndigoService">
<soap:address location="http://lujuntao/IISHostedService/Service.svc" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Exporting metadata for proxy generation
In this part of the lab,you will export the service metadata to a set of files that can later be distributed and used to generate a proxy,offline.
The files exported will be WSDL documents.
1. Launch the Visual Studio 2008 Command Prompt.
Run the following command to instruct SvcUtil to export the service metadata and its associated schemas for the HelloIndigoService:
如果路径名包含空格的话,需要给路径名加上双引号 还需要注意的一点是svcutil+ /d:+路径 /d:一定不能漏掉 /d是/directory的缩写
svcutil的用法https://msdn.microsoft.com/zh-cn/library/aa347733.aspx
svcutil /d:<YourLearningWCFPath>\Labs\Chapter1\IISHostedService /t:metadata http://localhost/IISHostedService/service.svc
This will generate two .wsdl files and two .xsd files in the solution directory.
//实际操作的时候,4个文件生成到C盘的VS默认路径:C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\SourceCode\GitHub\WCFTest 可以把这4个文件复制到解决方案路径下
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC>svcutil /"d:SourceCode\GitHub\WCFTest\Learning WCF\Labs\Chapter1\IISHostedService" /t:metadata http://localhost/IISHostedService/service.svc

2. Use these files to generate the application configuration and proxy required for clients to consume the service.
In the same command window,execute the following command:
svcutil /d:<YourLearningWCFPath>\Labs\Chapter1\IISHostedService\Client /o:serviceproxy.cs /config:app.config <YourLearningWCFPath>\Labs\Chapter1\
IISHostedService\*.wsdl <YourLearningWCFPath>\Labs\Chapter1\IISHostedService\*.xsd
The result of this command will be serviceproxy.cs and app.config files generated for the client application.
坑爹的,文件还是生成到了C盘里面,C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\SourceCode\GitHub\WCFTest\Learning WCF\Labs\Chapter1\IISHostedService\Client\

3. Add the two files just generated to the client project.
The proxy and configuration will be used to invoke the service hosted in IIS.
Go to the Client project and refresh the file list in Solution Explorer.
You should see the two new files appear;include them in the project.
4. Invoke the service using the generated proxy.
Open Program.cs in the code window and modify the Main( ) entry point adding code to create a proxy and invoke the HelloIndigo( ) operation.
The resulting additions are shown in bold in Example 1-15.
class Program
{
static void Main(string[] args)
{
HelloIndigoServiceClient proxy = new HelloIndigoServiceClient();
string s = proxy.HelloIndigo();
Console.WriteLine(s);
Console.WriteLine("Press <ENTER> to terminate Client.");
Console.ReadLine();
}
}
5. Compile and run the Client project. The output should be similar to that in earlier labs.
Web Site Templates
Many web site templates exist for creating new ASP.NET applications,
so it shouldn’t surprise you that there is a template to get you started with WCF.
The new WCF Service template can be used to create a new web site that is file-based or hosted in IIS.
This lab illustrates how to create an IIS-hosted site—the preferred way to test your services if you want an accurate depiction of security-related behavior.
Regardless,if you create an IIS- or file-based web site, the files generated are the same:
• A sample service contract and implementation
• A .svc endpoint for the sample service
• A web.config file with service model configuration settings for the sample service
@ServiceHost Declarations
IIS hosting requires a file-based endpoint with a .svc extension.
That’s because it relies on file-extension mappings to determine how incoming requests should be delegated.
The .svc extension is a new extension specific to WCF,and IIS knows to pass those requests to the service model for processing (via ASP.NET).
In this hosting environment,each unique service must have a .svc endpoint.
Chapter 4 discusses hosting in detail.
The .svc endpoint has one job to do—help the service model find the correct service type to host.
The @ServiceHost directive is the link between the incoming request and the service model.
In theory this directive can point to a service type declared with inline code based on a source file or belonging to a compiled assembly.
Similar to inline ASMX web services, .svc files can contain the actual source code for the service contract and type.
This makes it possible to deploy just the .svc file without any accompanying source,as shown in Example 1-16.
In this case,the Service attribute refers to the inline service type,and you can even enable inline debugging by setting the Debug attribute to true.
Although ASP.NET 2.0 introduced the possibility of compiling this inline code into an application assembly to protect the source,
I still consider this a tight coupling of the service implementation to the hosting environment—and that doesn’t promote reuse or deployment flexibility.
Example 1-16. Inline service code
<%@ ServiceHost Language="C#" Debug="true" Service="MyService" %>
using System;
using System.ServiceModel;
[ServiceContract( )]
public interface IMyService
{
[OperationContract]
string SomeOperation(string myValue);
}
public class MyService: IMyService
{
public string SomeOperation(string myValue)
{
return "Hello: " + myValue;
}
}
Another approach is to associate the .svc file with a code file in the web site as the original sample service did in this lab.
For ASP.NET 2.0 web sites this means placing the source in the \App_Code directory.
In this case,the Service attribute still refers to the service type,
but the CodeBehind attribute is present to indicate the location of its source file:
<% @ServiceHost Language=C# Debug="false" Service="MyService" CodeBehind="~/App_Code/MyService.cs" %>
This approach still couples the source to the host and lacks autonomous version control over services apart from their host.
Ultimately,the preferred way to associate a service type with its .svc endpoint is to add an assembly reference to the project and specify the fully qualified service type in the Service attribute:
<% @ServiceHost Service="MyNamespace.MyService" %>
This approach gives you the desired autonomy and reuse for the service.
Message-Based Activation
One of the benefits of using a fully featured host such as IIS or WAS is that it handles service activation on your behalf as messages arrive to the service.
In the first and second labs in this chapter,you hosted a service in a console application.
In all such self-hosting environments,you must explicitly run the host process before clients can invoke the service.
The ServiceHost instance is constructed and opened explicitly, and its lifetime is tied to the lifetime of the host process.
IIS and WAS,on the other hand,are system services that are equipped to process incoming messages even if the ServiceHost has not yet been constructed.
For example,when a request arrives for a particular .svc endpoint,the request is ultimately forwarded to the service model.
The service model looks at the @ServiceHost declaration to find the associated service type.
It then instantiates the ServiceHost instance for that type on your behalf,within an ASP.NET worker process.
The web.config settings are used to initialize the ServiceHost and then Open( ) is called—at which point the first request is forwarded to the appropriate channel listener.
Once the ServiceHost has been constructed and opened,subsequent requests for the same service are directed to it.
Simply put,with IIS or WAS hosting,you needn’t manually create the ServiceHost instance—this is handled for you by the host process.
This is called message-based activation.
The details of hosting are discussed in Chapter 4.
Another convenience of IIS and WAS hosting is that you can modify web.config settings for a service and the changes are reflected in subsequent calls without restarting IIS or WAS.
That’s because changes to configuration files are detected,and if necessary,a new application domain is constructed to service requests.
For example,if changes to the service model configuration require that a new ServiceHost instance be constructed to reflect the changes.
In a self-hosting environment,new settings are not known to the host process and thus are not reflected until you restart.
You could optionally build logic into the host to detect changes and recycle any ServiceHost instances.
With IIS and WAS,configuration changes are detected and a new ServiceHost is created to handle subsequent requests.
Browsing and Exporting Metadata
To consume a service,clients require access to service metadata,including the service contract,any custom data types,and binding requirements.
Earlier in this chapter,you learned how to enable the service metadata behavior and how to expose a metadata exchange endpoint to support proxy generation using SvcUtil.
This lab illustrates how to view metadata in the browser and how to export that metadata to files for offline consumption.
This capability is useful for a few reasons:
• For debugging purposes,it can be helpful to view the WSDL document,for example when trying to solve interoperability issues between platforms.
• Allowing client developers to eat up web server resources by browsing to dynamically created metadata is suboptimal.
Instead,once the contract is stable,you should export it and allow developers to browse static files.
• It may be helpful to send developers the WSDL document via some other delivery mechanism such as email.
This way they can generate proxies while offline.
Browsing metadata
Services may expose one or more endpoints,all of which are included in the service metadata.
When a WSDL document is generated,for example,this document describes the contracts exposed across all endpoints.
In other words,the WSDL document is one-to-one with the service.
You can browse to any service if they have an HTTP base address.
In the case of self-hosting environments,the <host> section of the service configuration can supply the base address.
For services hosted in IIS,the base address is the application directory in IIS with the .svc endpoint.
For example,in this lab you would browse to http://localhost/IISHostedService/Service.svc.
When you browse to a service’s base address you are presented with the service help page.
The service model dynamically generates this for you.
If you haven’t enabled the metadata behavior,the help page will still be presented with instructions on how to do this.
If you have enabled the metadata behavior but have forgotten to enable browsing,you’ll receive the same instructions.
In configuration,if you set httpGetEnabled to true,the help page will produce a link to the WSDL document
(Figures 1-27 and 1-28):
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
The service metadata behavior is required if you expose a metadata exchange endpoint for generating proxies,
but you may want to explicitly disable both the help page and metadata browsing
by adding the service debug behavior with httpHelpPageEnabled set to false and by setting httpGetEnabled to false:
<behavior name="serviceBehavior">
<serviceDebug httpHelpPageEnabled="false" />
<serviceMetadata httpGetEnabled="false" />
</behavior>
The WSDL document is dynamically generated each time metadata is accessed.
During development this is a useful feature to have,but once you publish your service to production,
it may be desirable to suppress dynamic generation to reduce overhead on the web server.
But what if you want to provide a link to static metadata?
An alternative is to leave metadata browsing enabled and provide a static file where the WSDL document can be retrieved.
This is achieved by providing a value for the externalMetadataLocation attribute:
<behavior name="serviceBehavior">
<serviceDebug httpHelpPageEnabled="false" />
<serviceMetadata httpGetEnabled="true" externalMetadataLocation="http://localhost/IISHostedService/www.thatindigogirl.com.samples.2006.06.wsdl"/>
</behavior>
Exporting metadata
To produce a static WSDL document,you can export service metadata using SvcUtil,as illustrated in this lab.
SvcUtil uses the mex endpoint to retrieve service metadata and save it to a WSDL document that can be stored on the filesystem.
The command switch for SvcUtil to export metadata is /t:metadata.
This command dumps the service metadata to several .wsdl and .xsd files in the specified directory:
svcutil /d:<YourLearningWCFPath>\Labs\Chapter1\IISHostedService /t:metadata http://localhost/IISHostedService/service.svc
The service model spreads the service description across multiple files.
These files have a hierarchical relationship where a root .wsdl imports child .wsdl and .xsd files.
In reality they are all one service description if you denormalize the output.
With this output,you can still use SvcUtil to generate code for client applications as this lab illustrates.
Learning WCF Chapter1 Hosting a Service in IIS的更多相关文章
- Learning WCF Chapter1 Generating a Service and Client Proxy
In the previous lab,you created a service and client from scratch without leveraging the tools avail ...
- Learning WCF Chapter1 Exposing Multiple Service Endpoints
So far in this chapter,I have shown you different ways to create services,how to expose a service en ...
- Learning WCF Chapter1 Creating a New Service from Scratch
You’re about to be introduced to the WCF service. This lab isn’t your typical “Hello World”—it’s “He ...
- Learning WCF Chapter1 Summary
SummaryThis chapter covered a lot of ground,beginning with a look at the purpose of WCF,the problems ...
- Fixing common issues when hosting a .NET 4.0 WCF service in IIS 7
http://sandrinodimattia.net/fixing-common-issues-when-hosting-a-net-4-0-wcf-service-in-iis-7/ Until ...
- WCF技术剖析之四:基于IIS的WCF服务寄宿(Hosting)实现揭秘
原文:WCF技术剖析之四:基于IIS的WCF服务寄宿(Hosting)实现揭秘 通过<再谈IIS与ASP.NET管道>的介绍,相信读者已经对IIS和ASP.NET的请求处理管道有了一个大致 ...
- Hosting Multiple Service Implementations On The Same Port With WCF
Hosting Multiple Service Implementations On The Same Port With WCF Recently I have been playing arou ...
- WCF - WAS Hosting
WCF - WAS Hosting To understand the concept of WAS hosting, we need to comprehend how a system is co ...
- XP机器上WCF采用X509证书加密时IIS读取证书的授权
XP机器上WCF采用X509证书加密时IIS读取证书的授权 XP下的授权命令为:winhttpcertcfg -g -c LOCAL_MACHINE\My -s 证书名称 -a "ASPNE ...
随机推荐
- Javaweb入门20160301 ---xml入门
一.xml语法 1.文档声明 用来声明xml的基本属性,用来指挥解析引擎如何去解析当前xml 通常一个xml都要包含并且只能包含一个文档声明 xml的文档必须在整个xml的最前面,在文档声明之前不能有 ...
- swift入门-day01
Swift 简介 简介 Swift 语言由苹果公司在 2014 年推出,用来撰写 OS X 和 iOS 应用程序 2014 年,在 Apple WWDC 发布 历史 2010 年 7 月,苹果开发者工 ...
- cordova 创建ios项目
cordova create fmscmsios1023 com.weilian.fmscms fmscms cd fmscms cd fmscmsios1023/ cordova platforms ...
- OC - 7.Foundation框架的简单介绍
OC语言-07-OC语言-Foundation框架 结构体 NSRange/CGRange 用来表示一个元素在另一个元素中的范围,NSRange等价于CGRange 包含两个属性: NSUInte ...
- javascript函数 第14节
<html> <head> <title>function</title> </head> <body> 1.函数形式<b ...
- nginx详细配置文件 (转)
Nginx的代码是由一个核心和一系列的模块组成, 核心主要用于提供Web Server的基本功能,以及Web和Mail反向代理的功能:还用于启用网络协议,创建必要的运行时环境以及确保不同的模块之间平滑 ...
- php安装过程中遇到的需要安装的问题
http://www.cnblogs.com/kristain/articles/3809243.html 借鉴php安装错误 2013-01-04 19:16:49 分类: 系统运维 环境: ...
- Makefile隐含规则和用到的默认变量
如果要使用隐含规则生成你需要的目标,你所需要做的就是不要写出这个目标的规则.那么,make会试图去自动推导产生这个目标的规则和命令,如果make可以自动推导生成这个目标的规则和命令,那么这个行为就是隐 ...
- centos 交换分区
内容来自:http://www.huzs.net/?p=1683 一般在桌面型的用不到,因为现在内存都比较大,服务器就不一样了,但是建议无论是在桌面还是服务器上,都设置 swap 以下操作都是在 ro ...
- [C#]async/Await 使用小计
如果指定使用 异步 或 异步 修饰符,方法是异步方法,可以实现以下两个函数. • 清单异步方法可以使用 Await 或指定的 等待 悬挂点. 等待运算符通知编译器异步方法不能继续点的过去,直到等待 ...