C#Webservice:Webmethod调用异步方法,返回Taskoff对象
我完全是一个网络服务的初学者,我跑了进去 下面的问题与Web服务和异步日志记录有关。(c#) 问题描述 我有一个向客户端(asp.net网站)返回一些数据的Web服务 到目前为止,效果相当不错 因为我想知道Web服务发布后会发生什么,所以我尝试实现一些简单的日志记录 以下类(简化)处理日志记录:C#Webservice:Webmethod调用异步方法,返回Taskoff对象,c#,web-services,asynchronous,async-await,C#,Web Services,Asynchronous,Async Await,我完全是一个网络服务的初学者,我跑了进去 下面的问题与Web服务和异步日志记录有关。(c#) 问题描述 我有一个向客户端(asp.net网站)返回一些数据的Web服务 到目前为止,效果相当不错 因为我想知道Web服务发布后会发生什么,所以我尝试实现一些简单的日志记录 以下类(简化)处理日志记录: public static class Logwriter { public static void writeToLog(string txt) { //writes log
public static class Logwriter
{
public static void writeToLog(string txt)
{
//writes log to db
}
}
我希望这是异步的,这样就不会减慢Web服务的速度
因此,我更改了WebMethod:
[WebMethod]
public async Task<MyClass> getData()
{
await Task.Run(() => Logwriter.writeToLog("Someone requested the WebMethod 'GetData'"));
//Do some work
return _myClassObject;
}
[WebMethod]
公共异步任务getData()
{
wait Task.Run(()=>Logwriter.writeToLog(“有人请求了WebMethod'GetData'));
//做些工作
返回_myClassObject;
}
在我更新asp.net网站上的ServiceReference之后,我注意到Web服务器不再返回“MyClass”对象,而是返回“TaskOffCustomClass”对象。我还没有找到从“TaskOffMyClass”对象获取“MyClass”对象的解决方案
问题
MyClass result = await service.getData();
或
Task=service.getData();
MyClass结果=task.result;
在第一个版本中,您的方法立即返回调用方,并在getData
完成后在wait
语句后恢复
在第二个版本中,对
task.Result
的调用会阻止执行,直到任务完成。您在这里非常混乱。希望Stephen Cleary也能回答,但您永远不应该在ASP.Net中Task.Run()
。您将使writeToLog
async。
至于返回任务,@Rene有一些很好的建议,但也不要在ASP.Net中使用.Result
,因为可能会出现死锁。
像日志记录这样的失火遗忘操作对用户来说异常复杂。
您最好将日志发送到队列进行处理
我对Web服务完全是个初学者
我建议你学习一个现代的框架。我都不知道阿斯姆克斯有多大了,现在。。。根据我所能找到的,它是“未死的”,但我认为这与Silverlight是同一种“未死的”。换句话说,它死了,但他们不想正式说它死了
特别是,我认为ASMX根本不理解async
或任务。我强烈建议您学习ASP.NET WebAPI(如果您真的需要SOAP,也可以学习WCF)
但是,如果您需要维护现有的web方法,那么
要意识到的第一件事是,你可能不想做一件“火与忘”的事。如果它工作得足够好,就保持这样:
[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;
}
我在我的博客上有对的描述。async
和wait
不像你想象的那样工作。在上面的代码中,您所做的只是使其中一些线程在不同的线程上运行,然后等待该线程完成运行,然后原始线程才能继续。我强烈建议您花更多时间学习async
和wait
。Eric Lippert的博客上有很多文章对此进行了解释。嗨@Damien_The_Unbliever,谢谢你的评论。我一定会看看埃里克·利珀斯的博客。嗨,斯蒂芬,谢谢你的支持。我读了@Crowcoder写的你的文章,它把我推向了正确的方向。不幸的是,我无法切换到ASP WebAPI或WCF,因为它是一个现有的Web服务。由于我们的团队对丢失一些日志数据没有意见,我继续使用HostingEnvironment。
[WebMethod]
public MyClass getData()
{
Logwriter.writeToLog("Someone requested the WebMethod 'GetData'");
//Do some work
return _myClassObject;
}
[WebMethod]
public MyClass getData()
{
HostingEnvironment.QueueBackgroundWorkItem(() => Logwriter.writeToLog("Someone requested the WebMethod 'GetData'"));
//Do some work
return _myClassObject;
}