簡體   English   中英

c#中多播委托的執行順序

[英]Sequence of execution in multicast delegates in c#

我讀到了

如果您正在使用多播委托,您應該知道鏈接到同一委托的方法將被調用的順序是正式未定義的。 因此,您應該避免編寫依賴於以任何特定順序調用此類方法的代碼。

但是當我嘗試使用此代碼時

using System;
namespace Wrox.ProCSharp.Delegates
{
    class Program
    {
        static void One()
        {
            Console.WriteLine("watch when i occur");
            throw new Exception("Error in watching");
        }
        static void Two()
        {
            Console.WriteLine("count");
        }
        static void Three()
        {
            Console.WriteLine("great");
        }
        static void Main()
        {
            Action d1 = Two;
            d1+=Two;
            d1+=Two;
            d1+=Two;
            d1+=One;
            d1+=Three;
            d1+=Three;
            d1+=Three;

            Delegate[] delegates = d1.GetInvocationList();
            foreach (Action d in delegates)
                try
                {
                    d1();
                }
                catch(Exception)
                {
                    Console.WriteLine("Exception Caught");

                }
        }
    }
}

這是我得到的輸出

count
count
count
count
watch when i occur
Exception Caught
count
count
count
count
watch when i occur
Exception Caught
count
count
count
count
watch when i occur
Exception Caught
count
count
count
count
watch when i occur
Exception Caught
count
count
count
count
watch when i occur
Exception Caught
count
count
count
count
watch when i occur
Exception Caught
count
count
count
count
watch when i occur
Exception Caught
count
count
count
count
watch when i occur
Exception Caught

很明顯,委托按照我編寫的非常指定的順序執行,並且Three()方法中沒有一個在引發異常的One()方法之前執行。

那么是不是我遺漏了什么,或者委托中的方法實際上是按照指定的順序執行的,而我從書中讀到的內容意味着其他的東西。

未定義- 行為被指定為任意的(比如你忘記了妻子的生日之后發生的事情......)所以依賴於任意的行為是潛在的危險。

可能是 5 年后,Microsoft 發布 .NET 7 並且您的程序的結果會發生變化。 那是“未定義”的意思,今天的任何測量都不會給你下一個版本的任何安慰,甚至在你的計算機和 Fred 的計算機之間。 所以觀察它只是有趣,但對可靠性沒有用處。 依靠你觀察到的東西在技術上是錯誤的。

有時,供應商會專門記錄一些未定義的內容,以便在實施中保持靈活性。

“正式未定義”只是意味着:無論發生什么都是實現細節; 它可能以您自然期望的方式工作; 它的工作方式可能完全不同,而且兩者都完全有效 對實現者沒有任何要求,它以任何特定的順序運行。 此外,這可能會在框架版本、目標和實現之間發生變化。

基本上:即使它做了你期望和想要的:不要依賴它繼續這樣做。

我不是高級程序員,但在查看您的代碼后,我可以發現一些錯誤。

你需要使用這個

Delegate[] delegates = d1.GetInvocationList();
            foreach (Action d in delegates)
            {
                try
                {
                    d();
                }
                catch(Exception e)
                {
                    Console.WriteLine("Exception Caught : "+e.Message);

                }
             }

而不是這個

Delegate[] delegates = d1.GetInvocationList();
            foreach (Action d in delegates)
                try
                {
                    d1();
                }
                catch(Exception)
                {
                    Console.WriteLine("Exception Caught");

                }

這就是我得到的

count
count
count
count
watch when i occur
Exception Caught : Error in watching
great
great
great

很明顯,調用列表中的委托是按順序執行的

此致

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM