C# Webservice: Webmethod, that calls an async method, returns Taskoff object

寵の児 提交于 2019-12-22 12:19:12

问题


I'm a total beginner with webservices and I ran in the following problem, which is about a webservice and asynchronous logging. (c#)

Problem Description

I have a webservice that returns some data to a client (asp.net website).

[WebMethod]
public MyClass getData()
{
    //Do some work
    return _myClassObject;
}

This works pretty good so far.

Because I want to know what is happening on the webservice once it is published, I tried to implement some simple logging.

The following class (simplified) handles the logging:

public static class Logwriter
{
   public static void writeToLog(string txt)
   {
       //writes log to db
   }
}

I want this to happen asynchronous, so it won't slow down the webservice.

Therefore i changed the WebMethod:

[WebMethod]
public async Task<MyClass> getData()
{
    await Task.Run(() => Logwriter.writeToLog("Someone requested the WebMethod 'GetData'"));
    //Do some work
    return _myClassObject;
}

After i updated the ServiceReference on my asp.net website I noticed that the webserver no longer returns a "MyClass"-Object, but a "TaskOffCustomClass"-Object. I have not found a solution to get the "MyClass"-Object from the "TaskOffMyClass"-Object, yet.

Questions

  1. How can I get my "MyClass" Object from "TaskOffMyClass"?

  2. Is there a possiblity to do the logging asynchronous and still return a "MyClass"-Object? (while using Task)

  3. I thought about doing the logging in a Thread, but I also read that it is recommended to use Task over Thread. How bad would be the impact of switching to Thread?


回答1:


I'm a total beginner with webservices

I recommend you learn a modern framework. I don't even know how old ASMX is, now... According to what I could find, it's "not dead", but I think that's the same kind of "not dead" that Silverlight is. In other words, it's dead but they don't want to officially say it's dead.

In particular, I don't think that ASMX understands async or tasks at all. I strongly recommend learning ASP.NET WebAPI (or WCF if you really want SOAP).

However, if you have existing web methods that you need to maintain, then...

The first thing to realize - as Crowcoder pointed out - is that you probably don't want to do fire-and-forget. If it works well enough, then just keep it like this:

[WebMethod]
public MyClass getData()
{
  Logwriter.writeToLog("Someone requested the WebMethod 'GetData'");
  //Do some work
  return _myClassObject;
}

If you recognize and accept the drawbacks of unprotected background operations (specifically, that they can be aborted without any way for you to detect that, meaning that your log may be missing some messages), then you can use something like HostingEnvironment.QueueBackgroundWorkItem:

[WebMethod]
public MyClass getData()
{
  HostingEnvironment.QueueBackgroundWorkItem(() => Logwriter.writeToLog("Someone requested the WebMethod 'GetData'"));
  //Do some work
  return _myClassObject;
}

I have a description of alternative approaches on my blog.




回答2:


You are very mixed up here. Hopefully Stephen Cleary will answer also, but you should never Task.Run() in ASP.Net. You would make writeToLog async. As far as returning Task, @Rene has some good advice, but also do not use .Result in ASP.Net because of potential for deadlocks. A fire and forget operation like logging is surprisingly complex to do right.. You would be better of sending your log to a queue for processing.




回答3:


You could either use

MyClass result = await service.getData();

or

Task<MyClass> task = service.getData();
MyClass result = task.Result;

In the first version, your method returns to the caller immediatly and is resumed after the await statement when getData finishes.
In the second version, the call to task.Result blocks execution until the Task is completed.



来源:https://stackoverflow.com/questions/36181107/c-sharp-webservice-webmethod-that-calls-an-async-method-returns-taskoff-objec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!