C# 在异步任务内异步执行多个任务

C# 在异步任务内异步执行多个任务,c#,wcf,asynchronous,task,C#,Wcf,Asynchronous,Task,我有以下WCF端点: public string AddPlace(Place placeBounds, ...) { FetchAllSocialPlatforms(placeBounds); Place newPlace = PlaceDB.AddPlace(placeBounds, ...); return newPlace; } …其中FetchAllSocialPlatforms()是: priva

我有以下WCF端点:

    public string AddPlace(Place placeBounds, ...)
    {

        FetchAllSocialPlatforms(placeBounds);

        Place newPlace = PlaceDB.AddPlace(placeBounds, ...);

        return newPlace;
    }
…其中
FetchAllSocialPlatforms()
是:

    private Task FetchAllSocialPlatforms(Place bounds)
    {
        try
        {
            Task<int> taskTwitter = FetchTwitter(bounds, user);
            Task<int> taskInstagram = FetchInstagram(bounds, user);
            Task<int> taskFlickr = FetchFlickr(bounds, user);
            Task<int> taskYouTube = FetchYouTube(bounds, user);

            Task.WhenAll(taskTwitter, taskInstagram, taskFlickr, taskYouTube);

            SendNotificationOnComplete(...); // Azure Service Bus / SignalR message back to app

        }
        catch (Exception ex)
        {
            Log.Error(...);
        }

        return null;
    }

FetchInstagram
FetchFlickr
FetchYouTube
都遵循相同的逻辑。

我修改了我的代码,它似乎可以正常工作

AddPlace(…)

获取所有社交平台(…)

FetchTwitter(…)


同样,
FetchInstagram
FetchFlickr
FetchYouTube
都遵循类似的代码逻辑。

因此
FetchAllSocialPlatforms
启动一系列任务来创建一些信息,但实际上您从未对这些信息做过任何事情。您可以启动任务,在不等待的情况下继续执行程序,并且在任务完成时从不做任何事情。该方法是同步的唯一方法是,如果每个
Fetch
方法都是同步的(您没有展示其实现)。此外,在web/api服务器上进行“后台处理”通常是错误的。您的WCF服务是否托管在ASP.NET中?@Servy我已经用更多信息更新了帖子。您的
FetchTwitter
实际上不是异步的。它是完全同步的。您的代码将生成一个警告,确切地告诉您这一点,因为您有一个
async
方法,其中没有
wait
。基本上,您的
Fetch
方法看起来是同步的,而不是异步的。您需要有一个异步方法来执行您想要执行的IO,才能真正从编写异步代码中获得任何好处。@AlbertTawil不,这些都不是真的。方法为
async
只意味着允许使用
wait
关键字。它不会导致该方法在另一个线程中运行,也不会使其异步。您的方法与调用
任务的常规同步方法没有任何区别。FromResult
在其结果上(从技术上讲,它也会在任务中封装任何异常,但您已经捕获它们并阻止它们逃逸该方法)。
Fetch
从何而来,如果是第三方库,则可能存在调用的异步版本。如果是您的函数,请向我们展示它,我们可能会向您展示如何使其异步。在IIS服务器上执行
任务。除非您的服务器利用率非常低,否则在IIS服务器上运行
很少是个好主意。这可能会使它更快地完成,但您将减少您的总容量。使用“真正的异步”调用而不是生成线程,可以在保持(或增加)容量的同时提供更快的代码。
    private async Task<int> FetchTwitter(Place bounds)
    {
        int count = 0;
        try
        {
            count = Fetch(bounds, PlatformType.Twitter);
        }
        catch (Exception ex)
        {
            Log.Error(...);
        }

        SendNotificationOnComplete(count, ...); // Azure Service Bus / SignalR message back to app

        return count;
    }
    public string AddPlace(Place placeBounds, ...)
    {

        FetchAllSocialPlatforms(placeBounds);

        Place newPlace = PlaceDB.AddPlace(placeBounds, ...);

        return new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(newPlace);
    }
    private async Task FetchAllSocialPlatforms(Place bounds)
    {
        try
        {
            Task taskTwitter = FetchTwitter(bounds);
            Task taskInstagram = FetchInstagram(bounds);
            Task taskFlickr = FetchFlickr(bounds);
            Task taskYouTube = FetchYouTube(bounds);

            var complete = Task.WhenAll(taskTwitter, taskInstagram, taskFlickr, taskYouTube);
            await complete.ContinueWith((c) =>
            {
                SendNotificationOnComplete(...); // Azure Service Bus / SignalR message back to app
            });

        }
        catch (Exception ex)
        {
            Log.Error(...);
        }

    }
    private async Task FetchTwitter(Place bounds)
    {
        var t = Task.Run(() =>
        {
            int count = 0;
            try
            {
                count = Fetch(bounds, PlatformType.Twitter);
            }
            catch (Exception ex)
            {
                Log.Error(...);
            }

            SendNotificationOnComplete(count, ...); // Azure Service Bus / SignalR message back to app

        });
        await t;
    }