C#基礎之委托異步

作者: Mr.X  來源: 博客園  發布時間: 2010-12-26 21:54  閱讀: 1068 次  推薦: 0   原文鏈接   [收藏]  
摘要:我們要談到的是C#基礎之委托異步,還有有別于C++里面的函數指針的。希望對大家有所幫助。

  大家知道委托就相當于C++里面的函數指針,相信大家都很很了解,看看如下簡單代碼來回想一下委托

 
public delegate void Ad();
xu xus
= new xu();
Ad b
= new Ad(xus.Add);
b
+= xus.ex;
b();
Console.ReadLine();
 
class xu
{

public void Add()
{

//Thread.Sleep(5000);
Console.WriteLine("sssssssssssssssssssss");
}

public void ex()
{

//Thread.Sleep(5000);
Console.WriteLine("aaaaaaaaaaaaaaaaaaaaa");
}
}

  這里我們看見 定義了一個ADD 的委托沒有參數沒有返回值 然后把委托指向ADD 和ex 兩個方法(多播委托) 然后執行b()  執行之后 結果大家應該知道 就是執行了這2個方法打印出 "ssssssssssssss"于"aaaaaaaaaaaaaaaa"。那如果變成下面這個形式呢?

 
public delegate int Ad(int x,int y);
static void Main(string[] args)
{
xu xus
= new xu();
Ad a
= new Ad(Add);
a
+= (int x, int y) => { return x - y; };
Console.WriteLine(a(
3,2));
Console.ReadLine();
}

static int Add(int x, int y)
{

//Thread.Sleep(2000);
return x + y;
}

static int ex(int x, int y)
{

//Thread.Sleep(5000);
return x - y;
}
}

  這段代碼 也是執行一個多播委托 但是輸出的結果會是什么樣的呢 答案是 輸出1,為什么前面那個委托會輸出2個方法 而這個委托只會輸出第二個方法的返回值?如果我們也想輸出2個返回值怎么辦呢?其實很簡單 代碼如下

 
public delegate int Ad(int x,int y);
static void Main(string[] args)
{
xu xus
= new xu();
Ad a
= new Ad(Add);
a
+= (int x, int y) => { return x - y; };
Delegate[] d
= a.GetInvocationList();
for (int i = 0; i < d.Length; i++)
{

if (d[i] is Ad)
{
Ad s
= (Ad)d[i];
Console.WriteLine(s(
3, 2));
}
}
Console.ReadLine();
}

static int Add(int x, int y)
{

// Thread.Sleep(2000);
return x + y;
}

static int ex(int x, int y)
{

//Thread.Sleep(5000);
return x - y;
}
}

  這里我們使用了一個GetInvocationList 方法來返回多播委托的調用列表 然后轉化ad 然后循環調用 最后顯示的結果就是5,1。委托的 復習我們就看到這里 現在回到正題 看看委托的異步調用。

 
public delegate int Ad(int x,int y);
static void Main(string[] args)
{
xu xus
= new xu();
Ad a
= new Ad(Add);
Console.WriteLine(a(
3, 3));
Console.WriteLine(
"start");
Console.ReadLine();
}

static int Add(int x, int y)
{
Thread.Sleep(
2000);
return x + y;
}

  運行這段代碼 會先停頓2秒鐘之后再顯示6 和start 因為我使用了sleep這個方法 它使該線程休眠2秒鐘,所以會在2秒之后顯示信息,但是這對用戶體驗來說是非常糟糕的,那我們怎么改善呢?看看如下代碼

 
public delegate int Ad(int x,int y);
static void Main(string[] args)
{
xu xus
= new xu();
Ad a
= new Ad(Add);
Console.WriteLine(a(
3, 3));
// Console.WriteLine("start");
IAsyncResult isa= a.BeginInvoke(3, 3, null, null);
while (!isa.IsCompleted)
{
Console.WriteLine(
"未完成");
}

int s= a.EndInvoke(isa);
Console.WriteLine(s.ToString());
Console.ReadLine();
}

static int Add(int x, int y)
{
Thread.Sleep(
2000);
return x + y;
}

static int ex(int x, int y)
{

//Thread.Sleep(5000);
return x - y;
}

  這里我們使用了begininvoke方法來異步執行 委托方法返回一個IAsyncResult 類型的值 代表委托執行的狀態,使用一個while循環 來判斷IsCompleted 如果沒有完成異步調用則不斷顯示“未完成” 如果完成endinvoke 則返回結果。但是這里需要不斷的詢問操作完成狀態 那么我們怎樣讓委托異步調用完成之后主動通知我們呢? 看看如下代碼

 
public delegate int Ad(int x,int y);
static void Main(string[] args)
{
xu xus
= new xu();
Ad a
= new Ad(Add);
Console.WriteLine(a(
3, 3));
IAsyncResult isa
= a.BeginInvoke(3, 3, new AsyncCallback(call), "edit by xyl");
//執行你想執行的代碼 這里我們還是用IsCompleted來代替
while (!isa.IsCompleted)
{
Console.WriteLine(
"未完成");
}
Console.ReadLine();
}

static void call(IAsyncResult isa)
{
AsyncResult ar
= (AsyncResult)isa;
Ad a
= (Ad)ar.AsyncDelegate;
Console.WriteLine(
"this is {0},{1}",a.EndInvoke(isa),ar.AsyncState);
}


static int Add(int x, int y)
{
Thread.Sleep(
2000);
return x + y;
}

static int ex(int x, int y)
{

//Thread.Sleep(5000);
return x - y;
}
}

  這里我們使用了一個call方法 注意它是沒有返回值的。把IAsyncResult轉換成AsyncResult注意少了個I然后轉換成AD 類型的委托 最后endinvoke 來返回值 這樣在委托異步執行完成之后會自動通知方法。呵呵 好了今天就說到這里吧。如果有說的不對的地方歡迎指正 大家一起學習一起進步。

0
0
 
 
 

文章列表

全站熱搜
創作者介紹
創作者 大師兄 的頭像
大師兄

IT工程師數位筆記本

大師兄 發表在 痞客邦 留言(0) 人氣()