我正在开发一个项目,需要使用特定格式的某些数据创建XML,将其发送到第三方服务,然后处理结果。这里的第三方功能是验证XML的数据和格式,然后创建一个证明一切符合requeriments的编码字符串(“戳”)。然后将此戳记添加到原始XML并存储在数据库中。
现在,仍然需要选择第三方,因此我必须以一种可以在发布前使用(到目前为止)两种不同的Web服务的方式创建我的项目,并有可能添加另一个,之后释放,改变所选择的。虽然最终结果是相同的(XML的“标记”),但每个Web服务的处理方式不同,例如:一个只返回戳记字符串,而另一个返回包含戳记的XML,而挂起的一个返回包含XML的zip文件的字节数组(我不知道谁告诉他们这是一个好主意,但是meh ,那是另一个故事)
考虑到这一点,我决定创建一个包装Web服务调用的静态类(每个Web服务一个方法)。所有这些方法都接收XML并返回“标记”XML或带有错误代码和消息的XML,以防出现问题。然后,处理数据的类只能创建所需的XML,调用其中一种方法,并处理结果。
到目前为止它看起来像这样:
public class EDocument
{
//This class handles all the data that will be included in the XML
public void Stamp()
{
//Here the XML string is created, sent to the correspondig third-party web service, and processed back
string xmlString;
//code to create the XML
//...
//If needed, I only have to change this line to call the corresponding method
WebServiceCalls.MainWebServiceCall stamper = WebServiceCalls.FirstServiceCall;
stamper.BeginInvoke(xmlString, StampCallback, null);
}
public void StampCallback(IAsyncResult ar)
{
AsyncResult result = (AsyncResult)ar;
WebServiceCalls.MainWebServiceCall caller = (WebServiceCalls.MainWebServiceCall)result.AsyncDelegate;
string response = caller.EndInvoke(ar);
//Call another async method to save to database the stamp, create the XML file, e-mail and store it, and notify the results...
//or create the exception with the error details and raise event here to notify the error
}
}
网络服务电话......
public static class WebServiceCalls
{
//Here I'll put the necessary web service calls. In the end there will be only one,
//but if on future the web service changes, a method with the same signature will be created here
//replacing the previous one
public delegate string MainWebServiceCall(string XmlData);
public static string FirstServiceCall(string XmlData)
{
FirstWebService firstWs = new FirstWebService();
string serviceResult = firstWs.Stamp(XmlData); //This returns only the stamp string
//Check the result, add the stamp to the original XML or create the error XML, and return...
return serviceResult;
}
public static string SecondServiceCall(string XmlData)
{
SecondWebService secondWs = new SecondWebService();
string serviceResult = secondWs.Stamp(XmlData); //This returns the XML with the stamp already added
//Check the result, create the error XML if something went wrong, and return...
return serviceResult;
}
public static string ThirdServiceCall(string XmlData)
{
ThirdWebService thirdWs = new ThirdWebService();
string serviceResultString;
byte[] serviceResult = thirdWs.Stamp(XmlData); //This (sigh) returns the byte array of a ZIP file...
//Unzip the file, check the result, create the corresponding XML and return...
return serviceResultString;
}
}
但是它击中了我...... 虽然我将异步调用包装器方法,但仍会同步调用Web服务方法。
问题是:这有什么缺点?我应该在每个调用方法上异步调用Web服务,处理回调,引发通知事件,在Edocument类上捕获它,处理结果并引发它的相应事件?考虑到这个项目可能有的未来变化,这不会让事情变得过于复杂吗?
或者这总体上是一个错误的方法吗?
请记住,这是C#4.0,所以(遗憾的是)async-await超出了范围。
答案 0 :(得分:1)
您根本没有使用异步IO。 Delegate.BeginInvoke
使用线程池。在服务器应用程序中,这几乎在所有情况下都是纯粹的破坏性。 Async IO is threadless.
使用同步代码或异步IO。
您似乎认为异步调用Web服务在内部是同步的(或者相反),可能会有缺点。不是这种情况。 Neither of the two parties can even tell how the other one is implemented.某个层中的异步只会影响该层。