Click here to Skip to main content
15,881,757 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
By Checking the result,i know , if the service calls are made asynchronously (in parallel), the total response time will be slightly more than 8000 millisecond,
NOW ,MY QUESTION IS the Class for "WeatherService" How to implement ,1 think ,I also use the EAP to solve the problem,but now TAP is the recommended approach to asynchronous programming in the .NET Framework,how I can achieve by the TAP
blow is my source code

1:Synchronous situation
ABOUT Controller
C#
public class DefaultController : Controller
    {
        // GET: Default
        public ActionResult IndexSynchronous(string city)
        {
           System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();
            NewsService newsService = new NewsService();
            string[] headlines = newsService.GetHeadlines();
            SportsService sportsService = new SportsService();
            string[] scores = sportsService.GetScores();
            WeatherService weatherService = new WeatherService();
            string[] forecast = weatherService.GetForecast();
            watch.Stop();
            TimeSpan timeSpan = watch.Elapsed;
            return Content(timeSpan.ToString());
        }
    }

ABOUT CLASS FOR SERVICE
C#
public class NewsService
    {     
        public string[] GetHeadlines()
        {
            Thread.Sleep(8000);
            string[] strs = { "关于赵薇的童年", "关于王宝强的童年" };
            return strs;
        }
    }
 public class SportsService
    {
        public string[] GetScores()
        {
            Thread.Sleep(8000);
            string[] strs = { "第一名分数为11", "第二名分数为22" };
            return strs;
        }
    }
 public class WeatherService
    { 
       public string[] GetForecast()
        {
            Thread.Sleep(8000);
            string[] strs = { "关于赵薇的童年", "关于王宝强的童年" };
            return strs;
        }
    }

URL:http://localhost:51424/Default/IndexSynchronous
RESULT:00:00:24.0008085
The following example shows an asynchronous version of the news portal Index action method.
2:Asynchronous situation
ABOUT AsyncController
C#
public class DefaultController : AsyncController
   {
               System.Diagnostics.Stopwatch watch = new     System.Diagnostics.Stopwatch();
       public void IndexAsync(string city)
       {
           watch.Start();
           AsyncManager.OutstandingOperations.Increment(3);
           NewsService newsService = new NewsService();
           newsService.GetHeadlinesCompleted += (sender, e) =>
           {
               AsyncManager.Parameters["headlines"] = e.strs;
               AsyncManager.OutstandingOperations.Decrement();
           };
           newsService.GetHeadlinesAsync();

           SportsService sportsService = new SportsService();
           sportsService.GetScoresCompleted += (sender, e) =>
           {
               AsyncManager.Parameters["scores"] = e.strs;
               AsyncManager.OutstandingOperations.Decrement();
           };
           sportsService.GetScoresAsync();

           WeatherService weatherService = new WeatherService();
           weatherService.GetForecastCompleted += (sender, e) =>
           {
               AsyncManager.Parameters["forecast"] = e.strs;
               AsyncManager.OutstandingOperations.Decrement();
           };
           weatherService.GetForecastAsync();

       }

       public ActionResult IndexCompleted(string[] headlines, string[] scores, string[] forecast)
       {
           string stsHeadlines = "";
           for (int i = 0; i < headlines.Length; i++)
           {
               stsHeadlines += headlines[i];
           }
           string stsScores = "";
           for (int i = 0; i < scores.Length; i++)
           {
               stsScores += scores[i];
           }
           string stsForecast = "";
           for (int i = 0; i < forecast.Length; i++)
           {
               stsForecast += forecast[i];
           }
           watch.Stop();
           TimeSpan timeSpan = watch.Elapsed;
           return Content(timeSpan.ToString() + stsHeadlines + stsScores + stsForecast);

       }

ABOUT CLASS FOR SERVICE
C#
public class NewsService
    {
        public string[] strs;
        public delegate void GetHeadlinesCompletedEventHandler(object Sender, GetHeadlinesCompletedEventArgs e);
        public event GetHeadlinesCompletedEventHandler GetHeadlinesCompleted;
        public class GetHeadlinesCompletedEventArgs :EventArgs
        {
            public readonly string[] strs;
            public GetHeadlinesCompletedEventArgs(string[] strs)
            {
                this.strs = strs;
            }
        }
        protected virtual void OnGetHeadlinesCompleted(GetHeadlinesCompletedEventArgs e)
        {
            if (GetHeadlinesCompleted != null)
            {  
                GetHeadlinesCompleted(this, e);   
            }
        } 
        public async void  GetHeadlinesAsync()
        {
            string[] result = await GetValueAsync();
           GetHeadlinesCompletedEventArgs e = new GetHeadlinesCompletedEventArgs(result);
           OnGetHeadlinesCompleted(e);
        }
        public Task<string[]> GetValueAsync( )
        {
            return Task.Run(() =>
            {
                Thread.Sleep(8000);
                string[] strss = { "关于赵薇的童年", "关于王宝强的童年" };
                return strss;
            });
        }
    }

  public class SportsService
    {
        public string[] strs;
        public delegate void GetScoresCompletedEventHandler(object Sender, GetScoresCompletedEventArgs e);
        public event GetScoresCompletedEventHandler GetScoresCompleted;
        public class GetScoresCompletedEventArgs : EventArgs
        {
            public readonly string[] strs;
            public GetScoresCompletedEventArgs(string[] strs)
            {
                this.strs = strs;
            }
        }
        protected virtual void OnGetScoresCompleted(GetScoresCompletedEventArgs e)
        {
            if (GetScoresCompleted != null)
            { 
                GetScoresCompleted(this, e);   
            }
        }
        public async void GetScoresAsync()
        {
            string[] result = await GetValueAsync();
            GetScoresCompletedEventArgs e = new GetScoresCompletedEventArgs(result);
            OnGetScoresCompleted(e);
        }
        public Task<string[]> GetValueAsync()
        {
            return Task.Run(() =>
            {
                Thread.Sleep(8000);
                string[] strs = { "第一名分数为11", "第二名分数为22" };
                return strs;
            });
        }
    }

 public class WeatherService
    {
        public string[] strs;
        public delegate void GetForecastCompletedEventHandler(object Sender, GetForecastCompletedEventArgs e);
        public event GetForecastCompletedEventHandler     GetForecastCompleted;
        public class GetForecastCompletedEventArgs : EventArgs
        {
            public readonly string[] strs;
            public GetForecastCompletedEventArgs(string[] strs)
            {
                this.strs = strs;
            }
        }
        protected virtual void OnGetForecastCompleted(GetForecastCompletedEventArgs e)
        {
            if (GetForecastCompleted != null)
            {  
                GetForecastCompleted(this, e);   
            }
        } 
        public async void GetForecastAsync()
        {
            string[] result = await GetValueAsync();
            GetForecastCompletedEventArgs e = new GetForecastCompletedEventArgs(result);
            OnGetForecastCompleted(e);
        }
        public Task<string[]> GetValueAsync()
        {
            return Task.Run(() =>
            {
                Thread.Sleep(8000);
                string[] strs = { "关于赵薇的童年", "关于王宝强的童年" };
                return strs;
            });
        }

    }

URL:http://localhost:51424/Default/Index
RESULT:
00:00:08.0519411


What I have tried:

var newsService = new NewsService();
  var sportsService = new SportsService();

  return View("Common",
      new PortalViewModel {
      NewsHeadlines = await newsService.GetHeadlinesAsync(),
      SportsScores = await sportsService.GetScoresAsync()
  });
Posted
Updated 21-Sep-17 6:34am
v5
Comments
Nathan Minier 21-Sep-17 9:43am    
It's not terribly clear where your process is breaking down. Please add more context, such as what you're trying to do and why it's not working.
Member 13390764 21-Sep-17 9:44am    
ok,sorry
Member 13390764 21-Sep-17 11:15am    
help me,thanks

1 solution

When you use await, the rest of the method doesn't execute until the task you're waiting for has finished. If that task takes 8 seconds, the next task won't start until at least 8 seconds later.

You need to start all three tasks at once, then wait for them all to finish.
C#
public async Task<ActionResult> IndexAsync(string city)
{
    var watch = System.Diagnostics.Stopwatch.StartNew();
    
    // Start all three tasks:
    
    var newsService = new NewsService();
    var newsTask = newsService.GetHeadlinesAsync(); // NB: No "await" here
    
    var sportsService = new SportsService();
    var sportsTask = sportsService.GetScoresAsync(); // Or here
    
    var weatherService = new WeatherService();
    var weatherTask = weatherService.GetForecastAsync(); // Or here
    
    // Wait for all three tasks to finish:
    await Task.WhenAll(newsTask, sportsTask, weatherTask);
    
    // Get the results:
    string[] headlines = await newsTask;
    string[] scores = await sportsTask;
    string[] forecast = await weatherTask;
    
    watch.Stop();
    
    TimeSpan timeSpan = watch.Elapsed;
    return Content(timeSpan.ToString());
}

NB: It would be much simpler to use async and await to make your test services asynchronous:
C#
public class NewsService
{     
    public async Task<string[]> GetHeadlinesAsync()
    {
        await Task.Delay(8000);
        string[] strs = { "...", "..." };
        return strs;
    }
}

Also, the AsyncController class[^] is only provided for backwards-compatibility with MVC 3. Assuming you're using v4 or later, it's no longer required. You can just make your actions return a Task<T> instead.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900