您的位置:首页 > 编程语言 > C#

C# 多线程的问题

2009-12-10 11:22 260 查看
1.invoke的功能,用法有些。
invoke 主要是处理多线程,在多线程中主要的有线程同步。
参照以下文档:
1.使用IAsyncResult asyncResult属性来判断异步调用是否完成

WaitOne的第一个参数表示要等待的毫秒数,在指定时间之内,WaitOne方法将一直等待,直到异步调用完成,并发出通知,WaitOne方法才返回true。当等待指定时间之后,异步调用仍未完成,WaitOne方法返回false,如果指定时间为0,表示不等待,如果为-1,表示永远等待,直到异步调用完成。

static void Main(string[] args)
{

NewTaskDelegate task = newTask;
IAsyncResult asyncResult = task.BeginInvoke(2000, null, null);
while (!asyncRe ==sult.IsCompleted)
{

Console.Write("*"); Thread.Sleep(100); } // 由于异步调用已经完成,因此, EndInvoke会立刻返回结果
int result = task.EndInvoke(asyncResult);
Console.WriteLine(result);
}

2.使用WaitOne方法等待异步方法执行完成
static void Main(string[] args)

{

NewTaskDelegate task = newTask;

IAsyncResult asyncResult = task.BeginInvoke(2000, null, null);

while (!asyncResult.AsyncWaitHandle.WaitOne(100, false))

{

Console.Write("*");

}

int result = task.EndInvoke(asyncResult); Console.WriteLine(result);

}

3、使用回调方式返回结果

上面介绍的几种方法实际上只相当于一种方法。这些方法虽然可以成功返回结果,也可以给用户一些提示,但在这个过程中,整个程序就象死了一样(如果读者在GUI程序中使用这些方法就会非常明显),要想在调用的过程中,程序仍然可以正常做其它的工作,就必须使用异步调用的方式。下面我们使用GUI程序来编写一个例子,代码如下:
private delegate int MyMethod();
private int method()
{
Thread.Sleep(10000);
return 100;
}
private void MethodCompleted(IAsyncResult asyncResult)
{
if (asyncResult == null)
return;
textBox1.Text = (asyncResult.AsyncState as MyMethod).EndInvoke(asyncResult).ToString();
}
private void button1_Click(object sender, EventArgs e)
{
MyMethod my = method;
IAsyncResult asyncResult = my.BeginInvoke(MethodCompleted, my);
}
要注意的是,这里使用了BeginInvoke方法的最后两个参数(如果被调用的方法含有参数的话,这些参数将作为BeginInvoke的前面一部分参数,如果没有参数,BeginInvoke就只有两个参数了)。第一个参数是回调方法委托类型,这个委托只有一个参数,就是IAsyncResult,如MethodCompleted方法所示。当method方法执行完后,系统会自动调用MethodCompleted方法。BeginInvoke的第二个参数需要向MethodCompleted方法中传递一些值,一般可以传递被调用方法的委托,如上面代码中的my。这个值可以使用IAsyncResult.AsyncState属性获得。
由于上面的代码通过异步的方式访问的form上的一个textbox,因此,需要按ctrl+f5运行程序(不能直接按F5运行程序,否则无法在其他线程中访问这个textbox,关于如果在其他线程中访问GUI组件,并在后面的部分详细介绍)。并在form上放一些其他的可视控件,然在点击button1后,其它的控件仍然可以使用,就象什么事都没有发生过一样,在10秒后,在textbox1中将输出100。

作者:佚名 http://www.diybl.com/course/4_webprogram/asp.net/netjs/2008714/133128.html

   using System;
   using System.Runtime.Remoting.Messaging;
   using System.Threading;
  namespace 等待句柄
  {
  //委托声明(函数签名)
  delegate string MyMethodDelegate();
  class MyClass
  {
   //要调用方法1
   public string Write1()
   {
   for(double i = 0; i < 100000000000;i++)
   Console.WriteLine("执行方法1");
   return "";
   }
   //要调用方法2
   public string Write2()
   {
   Console.WriteLine("执行方法2");
   return "22222222222222";
   }
   //要调用方法3
   public string Write3()
   {
   Console.WriteLine("执行方法3");
   return "33333333333333";
   }
   [STAThread]
   static void Main(string[] args)
   {
   MyClass myClass = new MyClass();
   MyMethodDelegate d1 = new MyMethodDelegate(myClass.Write1);
   MyMethodDelegate d2 = new MyMethodDelegate(myClass.Write2);
   MyMethodDelegate d3 = new MyMethodDelegate(myClass.Write3);
   AsyncResult myResult1,myResult2,myResult3; //此类封闭异步委托异步调用的结果,通过AsyncResult得到结果.
   myResult1 = (AsyncResult)d1.BeginInvoke(null,null); //调用
  
   myResult2 = (AsyncResult)d2.BeginInvoke(null,null);
  
   myResult3 = (AsyncResult)d3.BeginInvoke(null,null);
   //建立WaitHandle数组对象
   WaitHandle[] waitHandle = new WaitHandle[3]{myResult1.AsyncWaitHandle,myResult2.AsyncWaitHandle,myResult3.AsyncWaitHandle};
  /*
   try
   {
   //等待三个异步方法中的至少一个执行完成,才继续执行下面的语句
   WaitHandle.WaitAny(waitHandle);
   }
   catch(Exception ex)
   {
   throw new Exception(ex.Message);
   }
  */
   myResult1.AsyncWaitHandle.WaitOne(); //如果当前异步方法还没有完成,此异步方法执行完毕才往下执行
   myResult2.AsyncWaitHandle.WaitOne();
   myResult3.AsyncWaitHandle.WaitOne();
  /*
   myResult1.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1),false); //如果当前异步方法还没有完成,则等待一秒的时间执行此方法; 如果一秒后此方法还未完成的话,则不再等待,继续往下执行
   myResult2.AsyncWaitHandle.WaitOne();
   myResult3.AsyncWaitHandle.WaitOne();
  */
  
   Console.WriteLine("测试等待句柄"); //标记语句用.
   Console.Read();
   }
  }
  }
  本示例代码已经测试,能够正常运行!
http://www.wangchao.net.cn/bbsdetail_74766.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: