What’s the difference between a message and an event

來源:http://codebetter.com

 

What’s the difference between a message and an eventPosted by Dru Sellers on March 31, 2009
MassTransit has hit 0.6 RC1

 

On the Elegant Code Cast, I was asked what the difference was between a message and an event, and I really wasn’t happy with my answer. Well as luck would have it I recently started reading ‘The Power of Events’ in which the author gives a very good explanation (Below is a brief summation).

 

A message is just a structure. This structure could be as simple as the string ‘BUY’ or ‘SELL’ or it could be a complex structure like an object graph serialized to JSON. This is the message.

 

An event adds the components of ‘significance’ and ‘relativity’. Significance in this case is that the ‘message’ signifies some activity. The event’s form (again the message part) should contain data describing the event it signifies. Relativity is that it is related to other activities by time, causality and aggregation. Ok, so that introduces some other concepts. Time is easy, it happened on 12/31/2008. Causality is asking what caused this message. In MassTransit (MT), I am thinking of implementing this by placing the name of the message that is currently active in the message headers if you published any messages. Lastly, we have aggregation, if event A signifies the activity of the set of events B1, B2, B3… then A is an aggregation of the events Bi.

 

I look forward to finding ways to apply the thoughts and patterns in the book to MT in the near future. As for now though, 0.6 has hit RC status, and we are looking for feedback. So please pull the code down and run the samples. Let me know what you find and/or think.

 

1. 取得目前電腦序列埠名稱的陣列

2. 檔案總管,打開指定目錄

System.Diagnostics.Process.Start("explorer.exe", "D:\\"); 

3. 指示應用程式如何回應未處理的例外狀況

Application.SetUnhandledExceptionMode 方法

4. AppDomain.UnhandledException 事件

5. 在 DataGridView 子類別 (Subclass) 中變更 ENTER 鍵的行為

6. 取得螢幕解析度

7. 滑鼠指標變漏斗

this.Cursor = Cursors.WaitCursor;

Cursor.Current=Cursors.WaitCursor;

Application.UseWaitCursor=true; 

8. ThreadPool 實作-安德魯的部落格

9. C#--理解Thread.Sleep函數

 來源:http://bzegqunfe.blog.sohu.com/210706426.html

我們可能經常會用到Thread.Sleep 函數來使線程掛起一段時間。那麼你有沒有正確的理解這個函數的用法呢?思考下面這兩個問題: 1、假設現在是2008-4-7 12:00:00.000,如果我調用一下Thread.Sleep(1000) ,在2008-4-7 12:00:01.000 的時候,這個線程會不會被喚醒? 2、某人的代碼中用了一句看似莫明其妙的話:Thread.Sleep(0) 。既然是Sleep 0 毫秒,那麼他跟去掉這句代碼相比,有啥區別麼?我們先回顧一下操作系統原理。操作系統中,CPU競爭有很多種策略。 Unix系統使用的是時間片算法,而Windows則屬於搶占式的。在時間片算法中,所有的進程排成一個隊列。操作系統按照他們的順序,給每個進程分配一段時間,即該進程允許運行的時間。如果在時間片結束時進程還在運行,則CPU將被剝奪並分配給另一個進程。如果進程在時間片結束前阻塞或結束,則CPU當即進行切換。調度程序所要做的就是維護一張就緒進程列表,,當進程用完它的時間片後,它被移到隊列的末尾。所謂搶占式操作系統,就是說如果一個進程得到了CPU 時間,除非它自己放棄使用CPU ,否則將完全霸占CPU 。因此可以看出,在搶占式操作系統中,操作系統假設所有的進程都是“人品很好”的,會主動退出CPU 。在搶占式操作系統中,假設有若干進程,操作系統會根據他們的優先級、飢餓時間(已經多長時間沒有使用過CPU 了),給他們算出一個總的優先級來。操作系統就會把CPU 交給總優先級最高的這個進程。當進程執行完畢或者自己主動掛起後,操作系統就會重新計算一次所有進程的總優先級,然後再挑一個優先級最高的把CPU 控制權交給他。我們用分蛋糕的場景來描述這兩種算法。假設有源源不斷的蛋糕(源源不斷的時間),一副刀叉(一個CPU),10個等待吃蛋糕的人(10 個進程)。如果是Unix操作系統來負責分蛋糕,那麼他會這樣定規矩:每個人上來吃1 分鐘,時間到了換下一個。最後一個人吃完了就再從頭開始。於是,不管這10個人是不是優先級不同、飢餓程度不同、飯量不同,每個人上來的時候都可以吃1 分鐘。當然,如果有人本來不太餓,或者飯量小,吃了30秒鐘之後就吃飽了,那麼他可以跟操作系統說:我已經吃飽了(掛起)。於是操作系統就會讓下一個人接著來。如果是Windows 操作系統來負責分蛋糕的,那麼場面就很有意思了。他會這樣定規矩:我會根據你們的優先級、飢餓程度去給你們每個人計算一個優先級。優先級最高的那個人,可以上來吃蛋糕——吃到你不想吃為止。等這個人吃完了,我再重新根據優先級、飢餓程度來計算每個人的優先級,然後再分給優先級最高的那個人。這樣看來,這個場面就有意思了——可能有些人是PPMM,因此具有高優先級,於是她就可以經常來吃蛋糕。可能另外一個人的優先級特別低,於是好半天了才輪到他一次(因為隨著時間的推移,他會越來越飢餓,因此算出來的總優先級就會越來越高,因此總有一天會輪到他的)。而且,如果一不小心讓一個大胖子得到了刀叉,因為他飯量大,可能他會霸占著蛋糕連續吃很久很久,導致旁邊的人在那裡嚥口水。 。 。而且,還可能會有這種情況出現:操作系統現在計算出來的結果,是5號PPMM總優先級最高——高出別人一大截。因此就叫5號來吃蛋糕。 5號吃了一小會兒,覺得沒那麼餓了,於是說“我不吃了”(掛起)。因此操作系統就會重新計算所有人的優先級。因為5號剛剛吃過,因此她的飢餓程度變小了,於是總優先級變小了;而其他人因為多等了一會兒,飢餓程度都變大了,所以總優先級也變大了。不過這時候仍然有可能5號的優先級比別的都高,只不過現在只比其他的高一點點——但她仍然是總優先級最高的啊。因此操作系統就會說:5號mm上來吃蛋糕……(5號mm心裡鬱悶,這不剛吃過嘛……人家要減肥……誰叫你長那麼漂亮,獲得了那麼高的優先級) 。那麼,Thread.Sleep 函數是乾嗎的呢?還用剛才的分蛋糕的場景來描述。上面的場景裡面,5號MM在吃了一次蛋糕之後,覺得已經有8分飽了,她覺得在未來的半個小時之內都不想再來吃蛋糕了,那麼她就會跟操作系統說:在未來的半個小時之內不要再叫我上來吃蛋糕了。這樣,操作系統在隨後的半個小時裡面重新計算所有人總優先級的時候,就會忽略5號mm。 Sleep函數就是乾這事的,他告訴操作系統“在未來的多少毫秒內我不參與CPU競爭”。看完了Thread.Sleep 的作用,我們再來想想文章開頭的兩個問題。對於第一個問題,答案是:不一定。因為你只是告訴操作系統:在未來的1000毫秒內我不想再參與到CPU競爭。那麼1000毫秒過去之後,這時候也許另外一個線程正在使用CPU,那麼這時候操作系統是不會重新分配CPU的,直到那個線程掛起或結束;況且,即使這個時候恰巧輪到操作系統進行CPU分配,那麼當前線程也不一定就是總優先級最高的那個,CPU還是可能被其他線程搶占去。與此相似的,Thread有個Resume函數,是用來喚醒掛起的線程的。好像上面所說的一樣,這個函數只是“告訴操作系統我從現在起開始參與CPU競爭了”,這個函數的調用並不能馬上使得這個線程獲得CPU控制權。對於第二個問題,答案是:有,而且區別很明顯。假設我們剛才的分蛋糕場景裡面,有另外一個PPMM 7號,她的優先級也非常非常高(因為非常非常漂亮),所以操作系統總是會叫道她來吃蛋糕。而且,7號也非常喜歡吃蛋糕,而且飯量也很大。不過,7號人品很好,她很善良,她沒吃幾口就會想:如果現在有別人比我更需要吃蛋糕,那麼我就讓給他。因此,她可以每吃幾口就跟操作系統說:我們來重新計算一下所有人的總優先級吧。不過,操作系統不接受這個建議——因為操作系統不接受這個指令。於是7號mm就換了個說法:“在未來的0毫秒之內不要再叫我上來吃蛋糕了”。這個指令操作系統是接受的,於是此時操作系統就會重新計算大家的總優先級——注意這個時候是連7號一起計算的,因為“0毫秒已經過去了”嘛。因此如果沒有比7號更需要吃蛋糕的人出現,那麼下一次7號還是會被叫上來吃蛋糕。因此,Thread.Sleep(0)的作用,就是“觸發操作系統立刻重新進行一次CPU競爭”。競爭的結果也許是當前線程仍然獲得CPU控制權,也許會換成別的線程獲得CPU控制權。這也是我們在大循環裡面經常會寫一句Thread.Sleep(0) ,因為這樣就給了其他線程比如Paint線程獲得CPU控制權的權力,這樣界面就不會假死在那裡。末了說明一下,雖然上面提到說“除非它自己放棄使用CPU ,否則將完全霸占CPU”,但這個行為仍然是受到製約的——操作系統會監控你霸占CPU的情況,如果發現某個線程長時間霸占CPU,會強制使這個線程掛起,因此在實際上不會出現“一個線程一直霸占著CPU 不放”的情況。至於我們的大循環造成程序假死,並不是因為這個線程一直在霸占著CPU。實際上在這段時間操作系統已經進行過多次CPU競爭了,只不過其他線程在獲得CPU控制權之後很短時間內馬上就退出了,於是就又輪到了這個線程繼續執行循環,於是就又用了很久才被操作系統強制掛起。 。 。因此反應到界面上,看起來就好像這個線程一直在霸占著CPU一樣。末了再說明一下,文中線程、進程有點混亂,其實在Windows原理層面,CPU競爭都是線程級的,把這裡的進程、線程看成同一個東西就好了

 

8. WeTransfer 2GB檔案傳輸服務

https://www.wetransfer.com/

arrow
arrow
    全站熱搜

    bartler 發表在 痞客邦 留言(0) 人氣()