下面是“C# BeginInvoke实现异步编程方式”的完整攻略,包含两条示例说明:
C# BeginInvoke实现异步编程方式
什么是BeginInvoke
BeginInvoke是C#中可用于异步编程的一种方式。它可以在方法调用时将方法的执行放在一个独立的线程中进行,避免了在主线程上进行耗时操作时的阻塞。BeginInvoke和EndInvoke方法不仅支持参数传递,也支持异步返回结果。这种方法还允许我们处理异常和取消(Cancel)方法的调用。
下面是BeginInvoke方法的一般形式:
IAsyncResult BeginInvoke(Delegate del, Object[] args);
其中,Delegate del代表的是将要异步执行的方法,args是一个数组,其元素是给定委托方法要用到的参数。
示例一:使用异步编程实现下载图片
假设我们需要将一个包含多张图片的网页下载到本地电脑上,我们可以使用多线程来实现。为此,我们必须使用异步编程技术,否则在UI主线程上下载耗费时间过长将会导致用户界面的不响应。
1. 首先看代码:
public partial class Form1 : Form
{
private string[] urls = new[] {
"https://picsum.photos/300/200?image=1",
"https://picsum.photos/300/200?image=2",
"https://picsum.photos/300/200?image=3",
"https://picsum.photos/300/200?image=4",
"https://picsum.photos/300/200?image=5"
};
public Form1()
{
InitializeComponent();
}
private delegate void DownloadDelegate(string url, string fileName);
private void OnComplete(IAsyncResult ar)
{
var del = (DownloadDelegate)ar.AsyncState;
del.EndInvoke(ar);
}
private void button1_Click(object sender, EventArgs e)
{
foreach (var url in urls)
{
var fileName = Path.Combine(Application.StartupPath, $"{Guid.NewGuid()}.jpg");
var del = new DownloadDelegate(DownloadFileWithUrl);
del.BeginInvoke(url, fileName, OnComplete, del);
}
}
private void DownloadFileWithUrl(string url, string fileName)
{
using (var wc = new WebClient())
{
wc.DownloadFile(url, fileName);
}
}
}
2. 实现说明:
在这个例子中,我们使用了五张不同的图片网络地址来模拟需要下载的图片。在button1_Click方法中,我们遍历每一个网络地址,为每个地址生成一个不同的文件名,并将委托方法DownloadFileWithUrl、文件名和OnComplete回调函数作为参数分别传递给了DownloadDelegate的BeginInvoke方法中。
DownloadDelegate是该窗体的私有内部委托。在OnComplete回调函数中,我们使用了该委托的EndInvoke方法通知异步操作的完成。这里也要注意,在回调函数中还必须向该方法传递对应BeginInvoke中委托的引用,否则无法得到实际的结果值。
DownloadFileWithUrl是我们用于下载图片的公共方法。该方法使用WebClient对象来下载指定的url地址,并将结果保存在一个特定的文件中。
通过使用BeginInvoke读取每一个网页图片,我们可以避免UI线程的阻塞,同时也可以通过回调函数得到异步操作的结果。
示例二:使用委托异步执行方法
除了可以使用BeginInvoke来实现异步编程方法,还可以使用委托异步执行方法。下面看一个例子:
1. 代码实现:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private delegate void DoWorkDelegate(string text);
private void OnComplete(IAsyncResult ar)
{
var del = (DoWorkDelegate)ar.AsyncState;
del.EndInvoke(ar);
}
private void button1_Click(object sender, EventArgs e)
{
var del = new DoWorkDelegate(DoWork);
del.BeginInvoke("Asynchronous task completed.", OnComplete, del);
}
private void DoWork(string text)
{
Thread.Sleep(5000);
MessageBox.Show(text);
}
}
2. 实现说明:
在这个例子中,我们仅仅只是显示了一个简单的异步任务。该任务会在单独一个线程上休眠5秒钟,然后在一个MessageBox中显示传递进来的参数。要执行此异步任务,我们创建了一个名为DoWorkDelegate的委托,并将方法名DoWork作为参数传递给了委托。
一个异步操作总是绑定到一个回调函数。在您传递给BeginInvoke方法中的第三个参数中,您必须提供该委托的引用(有时也称为状态参数)。该引用在回调函数返回结果时使用。
总之,通过使用 BeginInvoke 和委托,您可以轻松地实现异步编程方法,避免应用程序的界面因耗时操作而无响应。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# BeginInvoke实现异步编程方式 - Python技术站