1.c#中异步委托怎样写
//创建委托对象HttpDownloadFileDel hdf = new HttpDownloadFileDel("与委托参数一致的方法名");hdf.BeginInvoke(“方法参数”, new AsyncCallback((f) =>{ while (!f.IsCompleted) { f.AsyncWaitHandle.WaitOne(200); } //你的逻辑,操作UI控件需要调度到UI线程。
//或者执行你的委托。 //fpd.Invoke(BasePath + "resource/" + fileName);}), "AsycState:OK");。
2.谁能简单明了的告诉我什么是异步,异步和委托有什么关系,还有就是
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
delegate void ZuoFanHandle();
static void Main(string[] args)
{
cZuoFan mZuoFan = new cZuoFan();
ZuoFanHandle ZuoFan = new ZuoFanHandle(mZuoFan.LaoPoZuoFan);
mZuoFan.FanShuLe += new cZuoFan.FanShuLeHandle(mZuoFan.ChiFan);
Console.Write("==================同步调用===================\r\n\r\n");
ZuoFan.Invoke();
Console.Write("我一直在看着老婆做饭,不用儿子叫,我也知道饭熟了\r\n\r\n");
Console.Write("==================异步调用===================\r\n\r\n");
ZuoFan.BeginInvoke(null, null);
Console.Write("老婆先去做吧,我看会电视,还可以干点别的,儿子叫我再吃饭\r\n");
Console.Read();
}
}
class cZuoFan
{
public delegate void FanShuLeHandle();
public event FanShuLeHandle FanShuLe;
public void LaoPoZuoFan()
{
Console.Write("老婆去做饭\r\n");
for (int i = 0; i <= 100; i = i + 10)
{
Console.Write(string.Format("老婆做饭完成了{0}%\r\n", i));
System.Threading.Thread.Sleep(500);
if (i == 100)
{
if (FanShuLe != null)
{
FanShuLe();
}
}
}
}
public void ChiFan()
{
Console.Write("饭熟了,儿子叫我吃饭了\r\n");
}
}
}
同步会等待结果的返回,就是 函数 调用完了,再接下去做事情,
异步 不会等待,提高CPU使用率
3.请问C#中的委托是什么
直接看MSDN或网上搜的大部分说的都是比较生硬的术语,你可以通俗的理解为将一个方法作为参数传递给另一个方法!也可以理解为:现有N个参数和返回值都相同的方法,在使用的时候根据需要一个个调用太繁琐,干脆把这些方法的规律(方法参数和返回值)总结出来,定义成一个委托!然后把要执行的方法交给委托去执行!+=操作实际上就是委托链,委托一次代理了若干个方法,以后执行时,我们调用委托来执行,委托会把所代理的方法一个个再执行!
委托在.net1.0就有,到了2.0时出现了匿名方法,也就是说委托要执行某一个方法,而这个方法并没有事先定义,随用随定义,连名字都没取,所以叫匿名方法。例:委托实例=delegate(int x,int y){return x+y;}实际就指向一个未取名的方法,而这个方法接收两个int参数,返回和。
到了.net3以后又更进一步,匿名方法还可以简写成:委托实例=(x,y)=>x+y; 这就是传说中的Lambda表达式,其本质是匿名方法,匿名方法本质是委托!
先通俗理解后,再看文档,你会恍然大悟!委托、匿名方法、Lambda表达式的概念其实很重要,如果你不理解的话是没办法学习好LinQ的。
这是我的理解,更多实例,你再搜吧~
4.C# Winform 多线程异步委托进度条
可以使用 BackgroundWorker 类进行操作。
写了一个demo程序可以参考一下,本例模拟从数据库获取 10000个学生的信息,用计算每个学生的总成绩和平均成绩作为耗时操作,显示进度条。主要代码:using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;namespace { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void button1_Click(object sender, EventArgs e) { BackgroundWorker worker = new BackgroundWorker(); worker.WorkerReportsProgress = true; worker.DoWork += worker_DoWork; worker.RunWorkerCompleted += worker_RunWorkerCompleted; worker.ProgressChanged += worker_ProgressChanged; worker.RunWorkerAsync(); } private void worker_ProgressChanged(object sender, e) { // 设置进度条进度 progressBar1.Value = e.ProgressPercentage; } private void worker_RunWorkerCompleted(object sender, e) { // 取出学生信息,绑定时 DataGridView studentBindingSource.DataSource = e.Result; } private void worker_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; List
5.c# 通过异步委托的执行结果更新UI界面
已经加注释了,你看一下吧:
lblStatus.Text = "执行中,请稍候……";
FunclongTask = new Func(delegate()
{
// 模拟长时间任务
Thread.Sleep(2000);
// 返回任务结果:5
return 5;
});
// 发起一次异步调用,实际上就是在.net线程池中执行longTask
// 这时由于是其它线程在工作,UI线程未被阻塞,所以窗体不会假死
longTask.BeginInvoke(ar =>
{
// 使用EndInvoke获取到任务结果(5)
int result = longTask.EndInvoke(ar);
// 使用Control.Invoke方法将5显示到一个label上,如果没有Invoke,
// 直接写lblStatus.Text="5",将会抛出跨线程访问UI控件的异常
Invoke(new Action(() => lblStatus.Text = "执行结果是:" + result));
}, null);
6.C#
using System;
using System.Threading;
//使用委托调用异步例子
namespace
{
class AsyncDelegatesBlocked
{
public static int Add(int op1, int op2, out int result)
{
Thread.Sleep(3000); // Simulating work
return (result = op1 + op2);
}
public delegate int AddDelegate(int op1, int op2,
out int result);//声明AddDelegate委托
static void Main()
{
int result;
/*定义一个AddDelegate类型委托add,将方法Add绑定到委托实例上*/
AddDelegate add = new AddDelegate(Add);
Console.WriteLine("[Main] Invoking the asynchronous " +
"Add method");
/*BeginInvoke 方法用于启动异步调用。它与您需要异步执行的方法具有相同的参数,还有两个额外的参数
*BeginInvoke 立即返回,不等待异步调用完成。BeginInvoke 返回 IasyncResult,可用于监视调用进度。*/
//定义IAsyncResult接口类型实例iAR
//6, 42, out result为异步执行的方法的参数列表
IAsyncResult iAR = add.BeginInvoke(6, 42, out result,
null, null);
// Here we're simulating doing some work before
// blocking on the Add method's completion.
Console.Write("[Main] Doing other work");
for (int i = 0; i < 10; i++)
{
Thread.Sleep(200);
Console.Write(".");
}
Console.WriteLine(" [Main] Waiting for Add to finish");
/*使用 IAsyncResult.AsyncWaitHandle 获取 WaitHandle,
* 使用它的 WaitOne 方法将执行一直阻塞到发出 WaitHandle 信号,然后调用 EndInvoke。
* 注意:异步调用完成时会发出 WaitHandle 信号,可以通过WaitOne 来等待它*/
iAR.AsyncWaitHandle.WaitOne();
Console.WriteLine("[Main] Add finished, cleaning up");
/*EndInvoke 方法用于检索异步调用结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;
* 如果异步调用未完成,EndInvoke 将一直阻塞到异步调用完成。
* EndInvoke 的参数包括所需要异步执行的方法的 out 和 ref 参数以及由 BeginInvoke 返回的 IAsyncResult。*/
add.EndInvoke(out result, iAR);
Console.WriteLine("[Main] The result is {0}", result);
Console.ReadLine();
}
}
}
7.c# 线程的异步调用与同步调用
我这样写 是 异步调用呢? 还是同步调用???
同步异步是一个相对的概念, 相对于UI主线程来说, 当然是异步的, 所以这样调用不会造成UI界面假死;相对于你新开的线程来说, 这是一个同步的过程, 必须等这个Invoke执行完才能往下进行, 如果下面还有代码的话。
如果你想异步得更彻底些, 就用BeginInvoke
是不是在同一个时间点只能有一个子线程在运行???
如果是单核的CPU, 当然只能有一个线程运行, 目前的CPU大多是双核及以上, 所以会有同时运行两个线程的可能。
8.c#中断异步操作
using System; using System.Net; using System.Threading; using System.Text; using System.IO; //Request 类用于通过 //异步调用传递数据 public class RequestState { const int BUFFER_SIZE = 1024; public StringBuilder RequestData; public byte[] BufferRead; public HttpWebRequest Request; public Stream ResponseStream; //创建适当编码类型的解码器 public Decoder StreamDecode = Encoding.UTF8.GetDecoder(); public RequestState() { BufferRead=new byte[BUFFER_SIZE]; RequestData = new StringBuilder(""); Request = null; ResponseStream = null; } } //ClientGetAsync发出异步请求 class ClientGetAsync { public static ManualResetEvent allDone=new ManualResetEvent(false); const int BUFFER_SIZE = 1024; public static void Main(string[] args) { if (args.Length 0) { //准备Char 数组缓冲区,用于向Unicode转换 Char[] charBuffer = new Char[BUFFER_SIZE]; //将字节流转换为Char 数组,然后转换为字符串 //len显示多少字符被转换为Unicode int len = rs.StreamDecode.GetChars(rs.BufferRead, 0, read, charBuffer, 0); String str = new String(charBuffer, 0, len); rs.RequestData.Append(str); IAsyncResult ar = responseStream.BeginRead(rs.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs); } else { if (rs.RequestData.Length > 1) { // 所有数据都已被读取,因此将其显示到控制台 string strContent; strContent = rs.RequestData.ToString(); Console.WriteLine(strContent); } //关闭响应流 responseStream.Close(); allDone.Set(); } return; } } 2. 判断控件的Handle是在当前线程中,则无需异步执行,否则要异步if (this.gcDC.InvokeRequired) { dlgt = new (OnLevelRegionChanged); this.Invoke(dlgt, new object[] { sender, ev }); } 3. 开启新线程可以通过开启新线程来执行异步操作,并给异步操作方法传递参数。
参数通常包括异步方法所需的所有数据。Thread thread=new Thread(new (GetDataFromWebService)); private static void GetDataFromWebService(object entity){ showWindow(); getData(); window.clost(); } 4.在界面线程外打开程序resultsCollection.AddRange(entity.DataCol); InsertIntoTable(resultsCollection, "", entity.tableName, entity.Schema, "", entity.IsNewFetch); if (window != null) { #region[Close progess window] System.Windows.Application.Current.Dispatcher.Invoke(new Action(() => { (window.WpfUIElement as System.Windows.Window).Close(); entity.SetNexValue(); })); #endregion }。
9.C#中的委托到底是什么概念
委托,简单理解是这样的.比如您要管您的孩子,把孩子送进了幼儿园.OK.此时您就把您的孩子委托给了幼儿园.当幼儿园放学,将孩子交还给您的手中.则是委托的回调.当然我这里的例子是说异步委托调用.您也可以同步.什么是同步委托调用?您去银行存钱.把钱给柜员.他们帮你点钞.存款然后给您存折或卡.那么您就相当于把钱委托给了柜员让他去执行存钱的这个函数.明白了么?Delegate delegate是C#中的一种类型,它实际上是一个能够持有对某个方法的引用的类。
与其它的类不同,delegate类能够拥有一个签名(signature),并且它"只能持有与它的签名相匹配的方法的引用"。它所实现的功能与C/C++中的函数指针十分相似。
它允许你传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m。但与函数指针相比,delegate有许多函数委托和事件在 .Net Framework中的应用非常广泛指针不具备的优点。
首先,函数指针只能指向静态函数,而delegate既可以引用静态函数,又可以引用非静态成员函数。在引用非静态成员函数时,delegate不但保存了对此函数入口指针的引用,而且还保存了调用此函数的类实例的引用。
其次,与函数指针相比,delegate是面向对象、类型安全、可靠的受控(managed)对象。也就是说,runtime能够保证delegate指向一个有效的方法,你无须担心delegate会指向无效地址或者越界地址。
实现一个delegate是很简单的,通过以下3个步骤即可实现一个delegate:1. 声明一个delegate对象,它应当与你想要传递的方法具有相同的参数和返回值类型。2. 创建delegate对象,并"将你想要传递的函数作为参数传入"。
3. 在要实现异步调用的地方,通过上一步创建的对象来调用方法。using System; public class MyDelegateTest { // 步骤1,声明delegate对象 public delegate void MyDelegate(string name); // 这是我们欲传递的方法,它与MyDelegate具有相同的参数和返回值类型 public static void MyDelegateFunc(string name) { Console.WriteLine("Hello, ", name); } public static void Main() { // 步骤2,创建delegate对象(实例??) MyDelegate md = new MyDelegate(MyDelegateTest.MyDelegateFunc); // 步骤3,调用delegate md("sam1111"); } } 输出结果是:Hello, sam1111 了解了delegate,下面我们来看看,在C#中对事件是如何处理的。
C#中的事件处理实际上是一种具有特殊签名的delegate,象下面这个样子:public delegate void MyEventHandler(object sender, MyEventArgs e); 其中的两个参数,sender代表事件发送者,e是事件参数类。MyEventArgs类用来包含与事件相关的数据,所有的事件参数类都必须从System.EventArgs类派生。
当然,如果你的事件不含参数,那么可以直接用System.EventArgs类作为参数。就是这么简单,结合delegate的实现,我们可以将自定义事件的实现归结为以下几步:1.定义delegate对象类型,它有两个参数,第一个参数是事件发送者对象,第二个参数是事件参数类对象。
2.定义事件参数类,此类应当从System.EventArgs类派生。如果事件不带参数,这一步可以省略。
3.定义"事件处理方法,它应当与delegate对象具有相同的参数和返回值类型"。4.用event关键字定义事件对象,它同时也是一个delegate对象。
5.用+=操作符添加事件到事件队列中(-=操作符能够将事件从队列中删除)。6.在需要触发事件的地方用调用delegate的方式写事件触发方法。
一般来说,此方法应为protected访问限制,既不能以public方式调用,但可以被子类继承。名字是OnEventName。
7. 在适当的地方调用事件触发方法触发事件。下面是一个简单的例子:using System; public class EventTest { // 步骤1,定义delegate对象 public delegate void MyEventHandler(object sender, System.EventArgs e); // 步骤2(定义事件参数类)省略 public class MyEventCls { // 步骤3,定义事件处理方法,它与delegate对象具有相同的参数和返回值类型 public void MyEventFunc(object sender, System.EventArgs e) { Console.WriteLine("My event is ok!"); } } // 步骤4,用event关键字定义事件对象 private event MyEventHandler myevent; private MyEventCls myecls; public EventTest() { myecls = new MyEventCls(); // 步骤5,用+=操作符将事件添加到队列中 this.myevent += new MyEventHandler(myecls.MyEventFunc); } // 步骤6,以调用delegate的方式写事件触发函数 protected void OnMyEvent(System.EventArgs e) { if(myevent != null) myevent(this, e); } public void RaiseEvent() { EventArgs e = new EventArgs(); // 步骤7,触发事件 OnMyEvent(e); } public static void Main() { EventTest et = new EventTest(); Console.Write("Please input ''a'':"); string s = Console.ReadLine(); if(s == "a") { et.RaiseEvent(); } else { Console.WriteLine("Error"); } } } 输出结果如下,红色为用户的输入:Please input 'a': a My event is ok!。