2014-11-21 53 views
0

我有一个非常大的方法,我想使异步访问。这些方法很复杂,有时很长。我能想到的方法是复制所有现有的方法并使其异步。但是当我必须做一些改变时,我必须编辑2种方法。代码在一个地方有更好的方法吗?使1方法异步以及在C#中同步

正如你所看到的代码基本相同。 是否可以将这两种方法合并为1?

public async Task ManufacturersToWebshopAsync(HttpContext httpContext, ManufacturerNopServiceClient manufacturerNopServiceClient, bool onlyChanged = false, bool includeNight = false) 
    { 
     Log.Verbose("ManufacturersToWebshop", "Start", ""); 

     // client 
     if (manufacturerNopServiceClient == null) 
     { 
      var host = httpContext.Request.Url.Host; 
      manufacturerNopServiceClient = GetManufacturerNopServiceClient(host); 
     } 

     var manufacturers = _manufacturerService.GetAllManufacturers(); 

     if (onlyChanged && includeNight) 
     { 
      manufacturers = manufacturers.Where(x => x.State == State.Changed || x.State == State.Night).ToList(); 
     } 
     else 
     { 
      if (onlyChanged) 
      { 
       manufacturers = manufacturers.Where(x => x.State == State.Changed).ToList(); 
      } 

      if (includeNight) 
      { 
       manufacturers = manufacturers.Where(x => x.State == State.Night).ToList(); 
      } 
     } 

     var tasks = new List<Task>(); 
     var total = manufacturers.Count(); 
     var count = 1; 

     foreach (var manufacturer in manufacturers) 
     { 
      Log.Information("ManufacturersToWebshop", "Manufacturer " + count + " van de " + total, ""); 
      //tasks.Add(ManufacturerToWebshop(httpContext, manufacturer, manufacturerNopServiceClient)); 
      await ManufacturerToWebshopAsync(httpContext, manufacturer, manufacturerNopServiceClient); 
      count++; 
     } 

     //await Task.WhenAll(tasks); 

     Log.Verbose("ManufacturersToWebshop", "End", ""); 
    } 

public void ManufacturersToWebshop(HttpContext httpContext, ManufacturerNopServiceClient manufacturerNopServiceClient, bool onlyChanged = false, bool includeNight = false) 
    { 
     Log.Verbose("ManufacturersToWebshop", "Start", ""); 

     // client 
     if (manufacturerNopServiceClient == null) 
     { 
      var host = httpContext.Request.Url.Host; 
      manufacturerNopServiceClient = GetManufacturerNopServiceClient(host); 
     } 

     var manufacturers = _manufacturerService.GetAllManufacturers(); 

     if (onlyChanged && includeNight) 
     { 
      manufacturers = manufacturers.Where(x => x.State == State.Changed || x.State == State.Night).ToList(); 
     } 
     else 
     { 
      if (onlyChanged) 
      { 
       manufacturers = manufacturers.Where(x => x.State == State.Changed).ToList(); 
      } 

      if (includeNight) 
      { 
       manufacturers = manufacturers.Where(x => x.State == State.Night).ToList(); 
      } 
     } 

     var total = manufacturers.Count(); 
     var count = 1; 

     foreach (var manufacturer in manufacturers) 
     { 
      Log.Information("ManufacturersToWebshop", "Manufacturer " + count + " van de " + total, ""); 
      ManufacturerToWebshop(httpContext, manufacturer, manufacturerNopServiceClient); 
      count++; 
     } 

     Log.Verbose("ManufacturersToWebshop", "End", ""); 
    } 
+1

如果您希望我们为您提供帮助,您需要发布一个小而重复的问题。在没有任何实际例子的情况下提出冗长的问题并没有帮助。 – 2014-11-21 08:17:32

+0

也许你可以从异步包装器中调用你的方法而不用改变这个方法 – Fedor 2014-11-21 08:21:08

+1

正确的答案取决于这些方法实际上在做什么。在某些情况下,你可能想用一些'Task'来包装一个同步方法。在其他情况下,您可能想要封装异步方法,直到完成为止。即使您的方法目前都是同步的,但并不排除它们可能更好地实现为异步。当然,每种方法的具体细节因每种方法所做工作的确切性质而异。 – 2014-11-21 08:29:21

回答

2

是否有可能与2种方法结合为1?

不是一种适用于所有情况的好方法。有hacks to write synchronous wrappers for asynchronous methodsother hacks to write asynchronous wrappers for synchronous methods - 但的选项在所有情况下都能正常工作。这个问题没有通用的通用解决方案。

我建议您考虑一下你的方法正在做什么,并决定它是否应该是异步的。例如,如果它在做I/O,那么它应该是异步的。然后,如果该方法应该是异步的,只需使其异步(没有同步版本)即可。

如果您正在更新代码,那么这将需要更新所有调用新异步方法的代码(以及调用这些方法的代码等)。如果此更新在整个系统中应用需要很长时间,则(临时)重复代码是我推荐的方法。但是,如果您不控制调用代码,那么您可能必须考虑链接文章中的一个黑客行为。请务必考虑每个方面的影响,并选择适合您的特定代码的方案。