C# 异步委托总结

C# 异步委托总结

C#的异步委托,总感觉十分的古老,虽然现在又新出了异步方法(async/await),但是在一些老的项目中并不支持新的语法,所以还得会用,参考一些网上大神的笔记,在这里将C#古老的异步委托,总结一下,以备不时之需。

1. BeginInvoke与EndInvoke
//建立委托
MyDelegate myDelegate = new MyDelegate(Hello);
//异步调用委托,获取计算结果
IAsyncResult result = myDelegate.BeginInvoke("Leslie", null, null);
//完成主线程其他工作
Console.WriteLine(".............");
//等待异步方法完成,调用EndInvoke(IAsyncResult)获取运行结果
string data = myDelegate.EndInvoke(result);
Console.WriteLine(data);

delegate string MyDelegate(string name);
static string Hello(string name)
{
Thread.Sleep(2000);
return "Hello " + name;
}
2. 轮询方式
//建立委托
MyDelegate myDelegate = new MyDelegate(Hello);
//异步调用委托,获取计算结果
IAsyncResult result = myDelegate1.BeginInvoke("Leslie", null, null);
//在异步线程未完成前执行其他工作
while (!result.IsCompleted)
{
	Thread.Sleep(200);
	Console.WriteLine("Main thead do work!");
}
while (!result.AsyncWaitHandle.WaitOne(200))
{
	Console.WriteLine("Main thead do work!");
}
string data = myDelegate.EndInvoke(result);
Console.WriteLine(data);
3. 回调函数

//建立委托
MyDelegate myDelegate = new MyDelegate(Hello);
//异步调用委托,获取计算结果
myDelegate.BeginInvoke("Leslie", new AsyncCallback(Completed), null);
//建立Person对象
Person person = new Person();
person.Name = "Elva";
person.Age = 27;
//异步调用委托,输入参数对象person, 获取计算结果
myDelegate.BeginInvoke("Leslie", new AsyncCallback(Completed3), person);
//在启动异步线程后,主线程可以继续工作而不需要等待
for (int n = 0; n < 6; n++)
{
	Console.WriteLine("  Main thread do work!");
}

static void Completed(IAsyncResult result)
{
	//获取委托对象,调用EndInvoke方法获取运行结果
	AsyncResult _result = (AsyncResult)result;
	MyDelegate myDelegate = (MyDelegate)_result.AsyncDelegate;
	string data = myDelegate.EndInvoke(_result);
	Console.WriteLine(data);
}

static void Completed3(IAsyncResult result)
{
	//获取委托对象,调用EndInvoke方法获取运行结果
	AsyncResult _result = (AsyncResult)result;
	MyDelegate myDelegate = (MyDelegate)_result.AsyncDelegate;
	string data = myDelegate.EndInvoke(_result);
	//获取Person对象
	Person person = (Person)result.AsyncState;
	string message = person.Name + "'s age is " + person.Age.ToString();
	Console.WriteLine(data + "\n" + message);
}

4. 异步读写文件

//把线程池的最大值设置为1000
ThreadPool.SetMaxThreads(1000, 1000);
ThreadPoolMessage("Start");
#region 异步写文件
//新立文件temp.txt
FileStream stream0 = new FileStream("temp.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, 1024, true);
byte[] bytes = new byte[16384];
string message = "An operating-system ThreadId...";
bytes = Encoding.Unicode.GetBytes(message);
//启动异步写入
stream0.BeginWrite(bytes, 0, (int)bytes.Length, new AsyncCallback(CallbackWrite), stream0);
stream0.Flush();
#endregion

#region 异步读文件
byte[] byteData = new byte[80961024];
FileStream stream1 = new FileStream("temp.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, 1024, true);
/*把FileStream对象,byte[]对象,
  长度等有关数据绑定到FileData对象中,
  以附带属性方式送到回调函数
*/
FileData fileData = new FileData();
fileData.Stream = stream1;
fileData.Length = (int)stream1.Length;
fileData.ByteData = byteData;
//启动异步读取
stream1.BeginRead(byteData, 0, fileData.Length, new AsyncCallback(CallbackRead), fileData);
#endregion
Console.ReadKey();
}

/// <summary>
/// 写文件的回调函数
/// </summary>
/// <param name="result"></param>
static void CallbackWrite(IAsyncResult result)
{
	//显示线程池现状
	Thread.Sleep(200);
	ThreadPoolMessage("CallbackWrite");
	//结束异步写入
	FileStream stream = (FileStream)result.AsyncState;
	stream.EndWrite(result);
	stream.Close();
}

//显示线程池现状
static void ThreadPoolMessage(string data)
{
	int a, b;
	ThreadPool.GetAvailableThreads(out a, out b);
	string message = string.Format("{0}\n  CurrentThreadId is {1}\n  " + "WorkerThreads is:{2} CompletionPortThreads is :{ 3}",
	data, Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString());
	Console.WriteLine(message);
}

public class FileData
{
	public FileStream Stream;
	public int Length;
	public byte[] ByteData;
}
/// <summary>
/// 读文件的回调函数
/// </summary>
/// <param name="result"></param>
static void CallbackRead(IAsyncResult result)
{
	ThreadPoolMessage("CallbackRead");
	//把AsyncResult.AsyncState转换为FileData对象,以FileStream.EndRead完成异步读取
	FileData fileData = (FileData)result.AsyncState;
	int length = fileData.Stream.EndRead(result);
	fileData.Stream.Close();
	//如果读取到的长度与输入长度不一致,则抛出异常
	if (length != fileData.Length)
		throw new Exception("Stream is not complete!");
	string data = Encoding.ASCII.GetString(fileData.ByteData, 0, fileData.Length);
	Console.WriteLine(data.Substring(2, 22));
}

5. 跨线程访问
//跨线程访问
Thread thread1 = new Thread(SetValues);
thread1.IsBackground = true;
thread1.Start();

//新线程给文本框赋值
private void SetValues()
{
	Action<int> setVal = (i) => { this.myTxtBox.Text = i.ToString(); };
	for (int i = 0; i < 10000; i++)
	{
		this.myTxtBox.Invoke(setVal, i);
	}
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值