c# begininvoke,c#异步begininvoke

  c# begininvoke,c#异步begininvoke

  IDE:Visual Studio 2008

  这一系列教程主要包括以下内容:

  1.BeginInvoke和EndInvoke方法

  2.线程类

  3.线程池

  4.线程同步的基础

  5.僵局

  6.线程同步的7种方法

  7.如何在线程中访问GUI组件

  一.螺纹概述

  在操作系统中,一个进程必须包含至少一个线程,然后,在某个时刻,需要同时执行同一个进程中的多个任务,或者为了提供者的性能,需要将要执行的任务拆分成多个子任务。这需要在同一个进程中打开多个线程。我们用C#写一个应用程序(控制台或者桌面),然后运行这个程序,打开windows任务管理器。此时,我们将看到该应用程序中包含的线程数,如下图所示。如果任务管理器没有“线程数”列,您可以[查看][选择列]显示“线程数”列。从上图可以看出,几乎所有的进程都有两个以上的线程。可见,线程是提升应用程序性能的重要手段之一,尤其是在多核CPU机器上。

  其次,使用Delegate的BeginInvoke和EndInvoke方法来操作线程。

  在C#中使用线程的方法有很多,使用委托的BeginInvoke和EndInvoke方法就是其中之一。BeginInvoke方法可以使用线程异步执行委托指向的方法。然后通过EndInvoke方法获取方法的返回值(EndInvoke方法的返回值就是被调用方法的返回值),或者确定方法已经被成功调用。我们可以通过四种方式从EndInvoke方法获得返回值。

  第三,直接使用EndInvoke方法获取返回值。

  当使用BeginInvoke异步调用方法时,如果方法没有完成,EndInvoke方法将一直阻塞,直到被调用的方法完成。如下面的代码所示:

  使用系统;

  使用系统。集合。泛型;

  使用系统。Linq

  使用系统。文本;

  使用系统。穿线;

  namespaceMyThread

  {

  课堂程序

  {

  privatestaticgintnewtask(intms)

  {

  控制台。WriteLine(“任务开始”);

  线程。睡眠(毫秒);

  random random=new random();

  intn=随机。下一个(10000);

  控制台。WriteLine(“任务已完成”);

  returnn

  }

  privatedelegateintNewTaskDelegate(intms);

  staticvoidMain(string[]args)

  {

  NewTaskDelegatetask=newTask

  IAsyncResultasyncResult=task。BeginInvoke(2000,null,null);

  //EndInvoke方法将被阻止2秒钟

  intresult=task。EndInvoke(async result);

  控制台。WriteLine(结果);

  }

  }

  }运行上述程序后,由于newTask方法被Sleep延迟了2秒,程序直到2秒后才输出最终结果(一个随机整数)。如果不调用EndInvoke方法,程序会立即退出。这是因为用BeginInvoke创建的线程是后台线程。一旦所有前台线程退出(主线程是前台线程),这个线程将结束线程并退出程序,不管后台线程是否已经执行完。前台和后台线程的细节将在后面的部分解释。

  读者可以用上面的程序做下面的实验。首先,在Main方法的开头添加以下代码:

  线程。睡眠(10000);

  在执行下面的代码之前,延迟Main方法10秒钟,然后按Ctrl+F5运行程序,打开企业管理器,观察当前程序中的线程数。假设线程数为4,10秒后,线程数将增加到5。这是因为调用BeginInvoke方法时,会建立一个线程来异步执行newTask方法,所以线程数会增加一个。

  四。使用IAsyncResult asyncResult属性判断异步调用是否完成。

  虽然上面的方法可以很好的实现异步调用,但是当调用EndInvoke方法得到调用结果时,整个程序就跟死了一样,不会让用户感觉太好。所以我们可以用asyncResult来判断异步调用是否完成,并显示一些提示信息。这样做可以增加用户体验。代码如下:

  staticvoidMain(string[]args)

  {

  NewTaskDelegatetask=newTask

  IAsyncResultasyncResult=task。BeginInvoke(2000,null,null);

  而(!异步结果。IsCompleted)

  {

  控制台。写( * );

  线程。睡眠(100);

  }

  //由于异步调用已经完成,EndInvoke会立即返回结果。

  intresult=task。EndInvoke(async result);

  控制台。WriteLine(结果);

  }因为是异步的,所以可能会在“任务开始”之前输出“*”,如上图所示。

  使用WaitOne方法等待异步方法完成。

  使用WaitOne方法是判断异步调用是否完成的另一种方法。代码如下:

  staticvoidMain(string[]args)

  {

  NewTaskDelegatetask=newTask

  IAsyncResultasyncResult=task。BeginInvoke(2000,null,null);

  而(!异步结果。AsyncWaitHandle.WaitOne(100,false))

  {

  控制台。写( * );

  }

  intresult=task。EndInvoke(async result);

  控制台。WriteLine(结果);

  } wait one的第一个参数表示等待的毫秒数。在指定的时间内,WaitOne方法将等待,直到异步调用完成并发出通知,waitone方法将返回true。等待指定时间后,异步调用仍未完成。WaitOne方法返回false。如果指定时间为0,则表示没有等待。如果为-1,则意味着永远等待,直到异步调用完成。

  不及物动词通过回调返回结果。

  以上方法其实只相当于一种方法。虽然这些方法可以成功返回结果,并给用户一些提示,但是在这个过程中,整个程序就像死了一样(如果读者在GUI程序中使用这些方法就会很明显)。如果程序在调用过程中还能正常做其他工作,就必须使用异步调用。让我们用GUI程序写一个例子。代码如下:

  privatedelegateintMyMethod();

  privateintmethod()

  {

  线程。睡眠(10000);

  return100

  }

  privatewidmethodcompleted(iasyncresult async result)

  {

  if(asyncResult==null)返回;

  文本框1。Text=(asyncResult。异步状态

  MyMethod)。EndInvoke(asyncResult)。ToString();

  }

  privatevidbutton 1 _ Click(object sender,EventArgse)

  {

  MyMethodmy=方法;

  IAsyncResultasyncResult=my。BeginInvoke(MethodCompleted,my);

  }注意这里使用的是BeginInvoke方法的后两个参数(如果被调用的方法包含参数,这些参数将是BeginInvoke的第一部分参数;如果没有参数,BeginInvoke只有两个参数)。第一个参数是回调方法委托类型,它只有一个参数,即IAsyncResult,如MethodCompleted方法所示。当method方法完成后,系统会自动调用MethodCompleted方法。BeginInvoke的第二个参数需要传递一些值给MethodCompleted方法,一般可以传递被调用方法的委托,比如上面代码中的my。该值可以通过使用IAsyncResult获得。AsyncState属性。

  由于上面的代码是以异步方式访问窗体上的一个textbox,所以需要按ctrl+f5才能运行程序(不能直接按F5运行程序,否则在其他线程中无法访问这个textbox。有关在其他线程中访问GUI组件的详细信息,请参考下一节)。并在窗体上放置一些其他可视控件。但是,点击button1后,其他控件仍然可以使用,就像什么都没发生一样。10秒钟后,textbox1中将输出100。

  七。其他组件的BeginXXX和EndXXX方法

  其他。net组件也有类似于BeginInvoke和EndInvoke的方法,比如系统的BeginGetResponse和EndGetResponse方法。HttpWebRequest类。下面是使用这两种方法的示例:

  按Ctrl+C复制代码

  按Ctrl+C复制代码

  出发地:www.cnblogs.com/nokiaguy/archive/2008/07/13/1241817.html 3358号公路

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • 设计一个简单的C#控制台应用程序,C#控制台程序,C# 创建控制台应用程序
  • 深入解析windows第8版,深入解析C#(第4版)
  • 数组代码,c# 数组操作,C# 数组实例介绍(图文)
  • 学会C#要多久,学会c#要多久,c#学习之30分钟学会XAML
  • 回溯法01背包问题c,回溯法求解01背包问题伪代码,C#使用回溯法解决背包问题实例分析
  • xml文件转义字符,xml转意字符,C# XML中的转义字符操作
  • winform 进度条控件,c# 进度条使用
  • winform 进度条控件,c# 进度条使用,C#使用winform实现进度条效果
  • winform backgroundworker,c# isbackground
  • winform backgroundworker,c# isbackground,C# BackgroundWorker用法详解
  • lua与c#交互,lua c#
  • lua与c#交互,lua c#,ToLua框架下C#与Lua代码的互调操作
  • linq c#,linq原理 c#
  • linq c#,linq原理 c#,c#中LINQ的基本用法实例
  • java decimal保留两位小数,sql中decimal函数保留2位小数,C#中decimal保留2位有效小数的实现方法
  • 留言与评论(共有 条评论)
       
    验证码: