[英]C# Webservice: Webmethod, that calls an async method, returns Taskoff object
我是网络服务的初学者,我遇到了以下问题,这是关于网络服务和异步日志记录的。 (C#)
问题描述
我有一个 Web 服务,可以将一些数据返回给客户端(asp.net 网站)。
[WebMethod]
public MyClass getData()
{
//Do some work
return _myClassObject;
}
到目前为止,这很好用。
因为我想知道 webservice 发布后发生了什么,所以我尝试实现一些简单的日志记录。
以下类(简化)处理日志记录:
public static class Logwriter
{
public static void writeToLog(string txt)
{
//writes log to db
}
}
我希望这异步发生,所以它不会减慢网络服务的速度。
因此我改变了 WebMethod:
[WebMethod]
public async Task<MyClass> getData()
{
await Task.Run(() => Logwriter.writeToLog("Someone requested the WebMethod 'GetData'"));
//Do some work
return _myClassObject;
}
在我的 asp.net 网站上更新 ServiceReference 后,我注意到网络服务器不再返回“MyClass”-Object,而是“TaskOffCustomClass”-Object。 我还没有找到从“TaskOffMyClass”-Object 中获取“MyClass”-Object 的解决方案。
问题
如何从“TaskOffMyClass”获取我的“MyClass”对象?
是否有可能进行异步日志记录并仍然返回“MyClass”-Object? (使用任务时)
我想过在线程中进行日志记录,但我也读到建议使用 Task over Thread。 切换到 Thread 的影响有多大?
我是网络服务的初学者
我建议你学习一个现代框架。 我什至不知道 ASMX 现在有多老了……根据我所能找到的,它“没有死”,但我认为这与 Silverlight 是同一种“没有死”。 换句话说,它已经死了,但他们不想正式说它已经死了。
特别是,我认为 ASMX 根本不理解async
或任务。 我强烈建议学习 ASP.NET WebAPI(如果你真的想要 SOAP,或者 WCF)。
但是,如果您有需要维护的现有 Web 方法,那么...
首先要意识到 - 正如Crowcoder 指出的那样- 你可能不想做一劳永逸的事情。 如果它运行得足够好,那么就保持这样:
[WebMethod]
public MyClass getData()
{
Logwriter.writeToLog("Someone requested the WebMethod 'GetData'");
//Do some work
return _myClassObject;
}
如果您认识到并接受未受保护的后台操作的缺点(特别是,它们可以被中止而您无法检测到,这意味着您的日志可能会丢失一些消息),那么您可以使用类似HostingEnvironment.QueueBackgroundWorkItem
东西:
[WebMethod]
public MyClass getData()
{
HostingEnvironment.QueueBackgroundWorkItem(() => Logwriter.writeToLog("Someone requested the WebMethod 'GetData'"));
//Do some work
return _myClassObject;
}
我在我的博客上描述了替代方法。
你在这里很混乱。 希望 Stephen Cleary 也会回答,但您永远不应该在 ASP.Net 中使用Task.Run()
。 您将使writeToLog
异步。 至于返回 Task,@Rene 有一些很好的建议,但也不要在 ASP.Net 中使用.Result
,因为可能会出现死锁。 像日志记录这样的即发即弃操作是非常复杂的。 . 您最好将日志发送到队列进行处理。
你可以使用
MyClass result = await service.getData();
或者
Task<MyClass> task = service.getData();
MyClass result = task.Result;
在第一个版本中,您的方法会立即返回给调用者,并在getData
完成时在await
语句之后恢复。
在第二个版本中,对task.Result
的调用会阻止执行,直到Task
完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.