我正在处理一个项目,该项目需要使用特定格式的某些数据创建XML,并将其发送给第三方服务,然后处理结果。这里的第三方功能是验证XML的数据和格式,然后创建一个编码的字符串(“标记”),证明一切符合要求。然后将该邮票添加到原始XML并存储在数据库中。异步方法内同步Web服务调用的缺点
现在,第三方还是要被选中的,所以我必须创建我的项目,以便它可以在发布之前使用两种不同的Web服务(至今),并有机会添加另一个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
}
}
Web服务调用...
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;
}
}
但随后打我... Althought我会打电话包装方法异步,Web服务方法仍将被同步调用。
问题是:这有什么缺点?我应该在每个调用者方法上异步调用Web服务,处理回调,引发通知事件,在Edocument类上捕获它,处理结果并引发相应的事件?考虑到这个项目可能的未来变化,这会不会让事情变得复杂?
或者这是总体上的问题的错误方法?
请记住,这是C#4.0,因此(可悲)异步等待超出范围。