【问题标题】:Make 1 method async as well as sync in C#在 C# 中使 1 个方法异步和同步
【发布时间】:2014-11-21 08:14:34
【问题描述】:

我有一组非常庞大的方法,我想让它们异步访问。这些方法很复杂,有时很长。我能想到的方法是复制所有现有方法并使它们异步。但是当我必须进行一些更改时,我必须编辑 2 个方法。有没有更好的方法将代码放在一个地方?

如您所见,代码基本相同。 是否可以将这两种方法合二为一?

    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", "");
    }

【问题讨论】:

  • 如果您希望我们帮助您,您需要发布一个小而完整的问题重现。在没有任何实际例子的情况下问一个冗长的问题是没有帮助的。
  • 也许您可以从异步包装器中调用您的方法,而无需更改此方法
  • 正确答案取决于这些方法的实际作用。在某些情况下,您可能想用一些Task 包装一个同步方法。在其他情况下,您可能希望用一些在完成之前阻塞的东西来包装一个异步方法。即使您的方法当前都是同步的,但这并不排除它们可以更好地实现为异步的可能性。当然,每个选项的具体细节会根据每种方法所做工作的确切性质而有所不同。

标签: c# asynchronous methods task sync


【解决方案1】:

这两种方法可以合二为一吗?

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    • 2013-05-14
    • 2018-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多