【问题标题】:Collection stacking ConcurrentQueue with multithreading集合堆叠 ConcurrentQueue 与多线程
【发布时间】:2017-07-24 15:46:31
【问题描述】:

关于这个主题的问题/答案不少(仅列出我找到的几个。还有更多)。

  1. C# Parallel - Adding items to the collection being iterated over, or equivalent?
  2. ConcurrentQueue with multithreading

感谢他们中的许多人,我想出了一个我希望能解决我的问题的方法。我也可能想多了。我有一个需要写入文本文件以进行日志记录的 api。现在该 api 被调用 N+ 次,并且在每次调用期间,它都需要记录请求。我不想做的是阻止请求在返回请求的数据之前必须等待记录日志。现在,日志不能仅仅被删除,因此如果文件当前正在使用,它还必须在每个请求上堆叠,为此使用 ReaderWriterLock。然后当文件没有被锁定时,我想写堆积日志。

我想出了这个,希望它能满足要求,但我认为它仍然会导致等待。

var wid = WindowsIdentity.GetCurrent().Token;
//add new log items
logs.Enqueue(helpers.createNewLog(requests));
string op;
while (logs.TryDequeue(out op))
{
    using (WindowsIdentity.Impersonate(wid))
    {
        //write to text file, location on shared drive
        var wrote = writers.WriteLog(op);
        //item cannot be written since file locked, add back to queue to try again
        if (!wrote)
        {
            logs.Enqueue(op);
        }
    }
 }

Logs 是一个像这样的全局变量

private static ConcurrentQueue<string> logs = new ConcurrentQueue<string>();

我觉得有些地方不对劲,但我正在为它是什么而苦苦挣扎,这将是满足要求并仍然在网络农场中工作的最佳方式。

【问题讨论】:

    标签: c# asp.net multithreading


    【解决方案1】:

    在我看来,您应该使用 BlockingCollection 而不是 ConcurrentQueue,这里有一个示例说明如何使用它,因为 Producer-Consumer 与您尝试做的事情相同。

    现在使用 ASP.Net,您可以插入模块来拦截每个请求,如果您想保存日志,我建议您注册一个模块而不是使用您的方法。在您的 Global.asax.cs 上,您有一个 Register 方法

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void Register()
        {
            //registering an HttpModule
            HttpApplication.RegisterModule(typeof(LogModule));
        }
    
        ....
    }
    
    
    public class LogModule: IHttpModule
    {
        public void Dispose()
        {
    
        }
    
        public void Init(HttpApplication context)
        {
            context.LogRequest += LogEvent;
        }
    
        private void LogEvent(object src, EventArgs args)
        {
            if (HttpContext.Current.CurrentNotification == RequestNotification.LogRequest)
            {
                if ((MvcHandler)HttpContext.Current.Handler != null)
                {
                    Debug.WriteLine("This was logged!");
                    //Save the information to your file
                }
            }
        }
    }
    

    希望对你有帮助

    【讨论】:

    • 我已经看过 BlockingCollection 并觉得它有点矫枉过正。我可能错了,所以我再看看。感谢您提供有关该模块的信息。
    • BlockingCollection 默认使用 ConcurrentQueue 作为底层存储。见msdn.microsoft.com/en-us/library/dd267312(v=vs.110).aspx
    • @TanveerBadar 是的,你是对的,在我看来,更好地操纵,但你是对的。
    猜你喜欢
    • 1970-01-01
    • 2016-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多