使1方法异步以及在C#中同步

时间:2014-11-21 08:14:35

标签: c# asynchronous methods task sync

我有一大堆方法可供异步访问。这些方法很复杂,有时很长。我能想到的方法是复制所有现有方法并使它们异步。但是当我必须进行一些更改时,我必须编辑2种方法。是否有更好的方法在一个地方使用代码?

正如您所看到的,代码基本相同。 是否可以将这两种方法合并为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 个答案:

答案 0 :(得分:2)

  

是否可以将这两种方法合并为1?

不适用于所有情况的好方法。有hacks to write synchronous wrappers for asynchronous methodsother hacks to write asynchronous wrappers for synchronous methods - 但 none 选项适用于所有方案。这个问题没有通用的通用解决方案。

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

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