使用BackgroundWorker而不是排队

时间:2018-08-06 17:03:10

标签: c# wcf message-queue

场景 我有一个必须同步调用我的Web服务的客户端,并且我必须在三秒钟内响应。我的Web服务同步调用另一个,通常需要大约12秒。

出于简化和时间限制,我正在考虑使用BackgroundWorker来实现排队。我有理由相信这是一次性的情况,并且可能看到的最大交易量约为每天100次。因此,我不认为通常会担心剥离过程的数量。

我读过的相关主题将其作为一种选择,但通常不是首选。

问题 这是一个方案吗?特别是因为我没有大量使用MSMQ,也没有很长时间,所以这是一个背景工作的合适方案吗?

1 个答案:

答案 0 :(得分:1)

您可以执行以下操作。发出请求后,在并发字典中添加调用服务所需的参数,这需要12秒。返回响应。然后,可以在后台使用类似在后台进行的工作。不愿意做其他处理等。

public static class BackGroundWorker
{
    private static Thread WorkerThread = null;

    private static readonly object WorkerLock = new object();

    private static readonly ManualResetEventSlim ShutdownEvent = new ManualResetEventSlim(false);

    private static ConcurrentDictionary<string, string> backGroundExecutingRequestIds = new ConcurrentDictionary<string, string>();

    public static void Start()
    {
        if (WorkerThread != null)
        {
            return;
        }

        lock (WorkerLock)
        {
            if (WorkerThread != null)
            {
                return;
            }

            ShutdownEvent.Reset();
            WorkerThread = new Thread(new ThreadStart(WorkerThreadProc));
            WorkerThread.Start();
        }
    }

    public static void Stop()
    {
        if (WorkerThread == null)
        {
            return;
        }

        ShutdownEvent.Set();
        WorkerThread.Join();
        WorkerThread = null;
    }

    private static void WorkerThreadProc() => WorkerThreadProcAsync().Wait();

    private static async Task WorkerThreadProcAsync()
    {
        try
        {
            while (!ShutdownEvent.Wait(0))
            {
                var ids = backGroundExecutingRequestIds.Take(25)?.Select(item => item.Key)?.ToList();
                while (ids?.Count > 0)
                {
                    //// Do the work of calling external Service which takes 12 seconds.
                    ids = Get the Next 25 Ids
                }

                await Task.Delay(TimeSpan.FromMilliseconds(100));
            }
        }
        catch(Exception ex)
        {
           ////LogException
        }
    }
}

}