-6

Hi I have the following method in my C# Web Service:

[WebMethod(EnableSession = true)]
        //[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]
        public object[] GetChartData()
        {

            System.Threading.Thread.Sleep(5000);

            string graphData = "";

            List<GoogleChartData> data = new List<GoogleChartData>();

            using (DBContext context = new DBContext ())
            {
                data = context.Campaings.AsNoTracking().Take(10).Select(c => new GoogleChartData
                {
                    Year = 2015,
                    USA = 1,
                    Mexico = 2,
                    Canada = 3
                }).ToList();
            }

            var chartData = new object[data.Count + 1];
            chartData[0] = new object[]{
                "Year",
                "USA",
                "Mexico",
                "Canada"
            };

            Random random = new Random();

            int j = 0;
            foreach (var i in data)
            {


                j++;
                chartData[j] = new object[] { i.Year.ToString(), random.Next(0, 1000), random.Next(0, 1000), random.Next(0, 1000) };
            }
            return  chartData;   

        }

I'm having issues when calling from the same application multiple times so I want to make it async. Im new to Async / Await.

Any clue?

VAAA
  • 14,531
  • 28
  • 130
  • 253
  • 5
    I'm having issues with figuring out what issues you have... You may want to look for some async/await samples first for framework you are using (looks like WebForms). – Alexei Levenkov Oct 20 '15 at 00:27
  • 2
    Given the nature of web development, `async/await` is unlikely to help you here. Perhaps you should be more specific as to what problems you are encountering? – BradleyDotNET Oct 20 '15 at 00:41
  • 2
    Why does your program have a 5 second sleep inside it? and what "issues" are you having exactly when you call the method multiple times. EDIT: You code has a lot of stuff that makes no sense, you do `.Select(c =>` but you never use `c` inside the select, why are you making a database call at all? – Scott Chamberlain Oct 20 '15 at 01:05
  • @VAAA web service requests are handled by separate background threads, you *don't* need to use `async/await` to make them asynchronous. What is the problem, where it the code that displays the problem? How are you making the calls to the service? . – Panagiotis Kanavos Oct 21 '15 at 13:08

2 Answers2

-1

I'm not quite clear about what you want, but if you want to use Await/Async in your function, here is your clue (suppose you're using Entity Framework 6):

public async Task<object[]> GetChartData()
{
    List<GoogleChartData> data;
    using (DBContext context = new DBContext ())
    {
        data = await context.Campaings.AsNoTracking().Take(10).Select(c => new GoogleChartData
        {
            Year = 2015,
            USA = 1,
            Mexico = 2,
            Canada = 3
        }).ToListAsync(); // Use ToListAsync()
    }

    // The rest are the same
}

EDIT!!!

As VAAA said in the comment, ToListAsync() is not available in his situation, so I try to find another solution.

Thanks to Scott Chamberlain's idea in his comment, the solution is: using Task.Run(() => GetChartData()) from the caller.

For those who are intending to use Task.Run() inside the GetChartData(): we should NOT make asynchronous wrappers for synchronous code.

Triet Doan
  • 11,455
  • 8
  • 36
  • 69
  • Let's say I dont have ToListAsync() , how can I convert it to async – VAAA Oct 20 '15 at 00:56
  • 1
    @VAAA You need to find the async version of whatever method from whatever library you are using. If there is no async method you will likely get better performance by not making it async. – Scott Chamberlain Oct 20 '15 at 01:03
  • 2
    @AnhTriet Doing a `Task.Run` inside a function "to make it async" is almost never a good idea to do, a much better chose is let the caller do `Task.Run(() => GetChartData())`, and have the Task.Run be made by the caller who wants it run in a background thread. You should [not to make asynchronous wrappers for synchronous code](http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx). – Scott Chamberlain Oct 20 '15 at 01:08
  • OK, I totally agree with you. I'll update my answer :) Thanks. – Triet Doan Oct 20 '15 at 01:12
  • Web service requests already run in separate threads. Using `async/await` won't make the method asynchronous, it *already* is. `async/await` in this case means that the *request* thread can be released while waiting for the database to respond. Other requests are already serviced by *other* threads – Panagiotis Kanavos Oct 21 '15 at 13:04
-3

Have a look at Creating an async webservice method

[WemMethod]
public async Task<List<ErrorLog>> GetAllErrorLogs()
{
List<ErrorLog> errorLogs = new List<ErrorLog>();
await System.Threading.Tasks.Task.Run(() => {
    errorLogs = ErrorLogRepository.GetAllErrorLogs();
})
if (errorLogs == null)
    return new List<ErrorLog>();
return errorLogs;
}
Community
  • 1
  • 1
Sami
  • 3,686
  • 4
  • 17
  • 28
  • 2
    Doing what you did does nothing except increase overhead on the server by spawning a new thread. The only thing you accomplished is you made his program slower. If you are doing a `Task.Run` in a IIS project you are likely doing something wrong. – Scott Chamberlain Oct 20 '15 at 01:02