2017-07-24 28 views
0

有關這個主題的幾個問題/答案(只列出了我發現的一對夫婦,還有更多)。收集堆疊ConcurrentQueue與多線程

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

日誌是一個全球性的,像這樣

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

我覺得自己是不是正確的,但我與它是什麼,這將是最好的方式,以使要求掙扎在網上農場見面並且仍然工作。

回答

1

在我看來,你應該使用BlockingCollection而不是ConcurrentQueue,這裏是一個如何使用它的例子,因爲Producer-Consumer與你正在嘗試做的事情是一樣的。

現在用ASP.Net,你可以插入模塊來攔截每個請求,如果你想保存日誌,我建議你註冊一個模塊,而不是用你的方法。在你的Global.asax.cs你有一個註冊方法

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 
      } 
     } 
    } 
} 

希望這有助於

+0

我已經看了看BlockingCollection,並認爲這是一個有點矯枉過正。我可能是錯的,所以我會再看一次。感謝關於模塊的信息。 –

+0

BlockingCollection 默認使用ConcurrentQueue 作爲底層存儲。請參閱https://msdn.microsoft.com/en-us/library/dd267312(v=vs.110).aspx –

+0

@TanveerBadar是的,在我看來,這是對的,但是你是對的。 – Zinov