青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

道。道。道

安全特性不等于安全的特性

   :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理

常用鏈接

搜索

  •  

最新評(píng)論

問(wèn)題的產(chǎn)生:

  我的WinForm程序中有一個(gè)用于更新主窗口的工作線程(worker thread),但文檔中卻提示我不能在多線程中調(diào)用這個(gè)form(為什么?),而事實(shí)上我在調(diào)用時(shí)程序常常會(huì)崩掉。請(qǐng)問(wèn)如何從多線程中調(diào)用form中的方法呢?

  解答:

  每一個(gè)從Control類中派生出來(lái)的WinForm類(包括Control類)都是依靠底層Windows消息和一個(gè)消息泵循環(huán)(message pump loop)來(lái)執(zhí)行的。消息循環(huán)都必須有一個(gè)相對(duì)應(yīng)的線程,因?yàn)榘l(fā)送到一個(gè)window的消息實(shí)際上只會(huì)被發(fā)送到創(chuàng)建該window的線程中去。其結(jié)果是,即使提供了同步(synchronization),你也無(wú)法從多線程中調(diào)用這些處理消息的方法。大多數(shù)plumbing是掩藏起來(lái)的,因?yàn)閃inForm是用代理(delegate)將消息綁定到事件處理方法中的。WinForm將Windows消息轉(zhuǎn)換為一個(gè)基于代理的事件,但你還是必須注意,由于最初消息循環(huán)的緣故,只有創(chuàng)建該form的線程才能調(diào)用其事件處理方法。如果你在你自己的線程中調(diào)用這些方法,則它們會(huì)在該線程中處理事件,而不是在指定的線程中進(jìn)行處理。你可以從任何線程中調(diào)用任何不屬于消息處理的方法。

  Control類(及其派生類)實(shí)現(xiàn)了一個(gè)定義在System.ComponentModel命名空間下的接口 -- ISynchronizeInvoke,并以此來(lái)處理多線程中調(diào)用消息處理方法的問(wèn)題:

public interface ISynchronizeInvoke
{
 object Invoke(Delegate method,object[] args);
 IAsyncResult BeginInvoke(Delegate method,object[] args);
 object EndInvoke(IAsyncResult result);
 bool InvokeRequired {get;}
}

  ISynchronizeInvoke提供了一個(gè)普通的標(biāo)準(zhǔn)機(jī)制用于在其他線程的對(duì)象中進(jìn)行方法調(diào)用。例如,如果一個(gè)對(duì)象實(shí)現(xiàn)了ISynchronizeInvoke,那么在線程T1上的客戶端可以在該對(duì)象中調(diào)用ISynchronizeInvoke的Invoke()方法。Invoke()方法的實(shí)現(xiàn)會(huì)阻塞(block)該線程的調(diào)用,它將調(diào)用打包發(fā)送(marshal)到 T2,并在T2中執(zhí)行調(diào)用,再將返回值發(fā)送會(huì)T1,然后返回到T1的客戶端。Invoke()方法以一個(gè)代理來(lái)定位該方法在T2中的調(diào)用,并以一個(gè)普通的對(duì)象數(shù)組做為其參數(shù)。

  調(diào)用者還可以檢查InvokeRequired屬性,因?yàn)槟慵瓤梢栽谕痪€程中調(diào)用ISynchronizeInvoke也可以將它重新定位(redirect)到其他線程中去。如果InvokeRequired的返回值是false的話,則調(diào)用者可以直接調(diào)用該對(duì)象的方法。

  比如,假設(shè)你想要從另一個(gè)線程中調(diào)用某個(gè)form中的Close方法,那么你可以使用預(yù)先定義好的的MethodInvoker代理,并調(diào)用Invoke方法:

Form form;
/* obtain a reference to the form,
then: */
ISynchronizeInvoke synchronizer;
synchronizer = form;

if(synchronizer.InvokeRequired)
{
MethodInvoker invoker = new
MethodInvoker(form.Close);
synchronizer.Invoke(invoker,null);
}
else
form.Close();

  ISynchronizeInvoke不僅僅用于WinForm中。例如,一個(gè)Calculator類提供了將兩個(gè)數(shù)字相加的Add()方法,它就是通過(guò)ISynchronizeInvoke來(lái)實(shí)現(xiàn)的。用戶必須確定ISynchronizeInvoke.Invoke()方法的調(diào)用是執(zhí)行在正確的線程中的。

  C# 在正確的線程中寫入調(diào)用

  列表A. Calculator類的Add()方法用于將兩個(gè)數(shù)字相加。如果用戶直接調(diào)用Add()方法,它會(huì)在該用戶的線程中執(zhí)行調(diào)用,而用戶可以通過(guò)ISynchronizeInvoke.Invoke()將調(diào)用寫入正確的線程中。

  列表A:

public class Calculator : ISynchronizeInvoke
{
 public int Add(int arg1,int arg2)
 { 
  int threadID = Thread.CurrentThread.GetHashCode();
  Trace.WriteLine( "Calculator thread ID is " + threadID.ToString());
  return arg1 + arg2;
 }
 //ISynchronizeInvoke implementation
 public object Invoke(Delegate method,object[] args)
 {
  public IAsyncResult BeginInvoke(Delegate method,object[] args)
  {
   public object EndInvoke(IAsyncResult result)
   {
    public bool InvokeRequired
    {
    }
   }
   //Client-side code
   public delegate int AddDelegate(int arg1,int arg2);

    int threadID = Thread.CurrentThread.GetHashCode();
    Trace.WriteLine("Client thread ID is " + threadID.ToString());

    Calculator calc;
    /* Some code to initialize calc */

    AddDelegate addDelegate = new AddDelegate(calc.Add);

    object[] arr = new object[2];
    arr[0] = 3;
    arr[1] = 4;

    int sum = 0;
    sum = (int) calc.Invoke(addDelegate,arr);
    Debug.Assert(sum ==7);

    /* Possible output:
    Calculator thread ID is 29
    Client thread ID is 30
    */

  或許你并不想進(jìn)行同步調(diào)用,因?yàn)樗淮虬l(fā)送到另一個(gè)線程中去了。你可以通過(guò)BeginInvoke()和EndInvoke()方法來(lái)實(shí)現(xiàn)它。你可以依照通用的.NET非同步編程模式(asynchronous programming model)來(lái)使用這些方法:用BeginInvoke()來(lái)發(fā)送調(diào)用,用EndInvoke()來(lái)實(shí)現(xiàn)等待或用于在完成時(shí)進(jìn)行提示以及收集返回結(jié)果。

  還值得一提的是ISynchronizeInvoke方法并非安全類型。 類型不符會(huì)導(dǎo)致在執(zhí)行時(shí)被拋出異常,而不是編譯錯(cuò)誤。所以在使用ISynchronizeInvoke時(shí)要格外注意,因?yàn)榫庉嬈鳠o(wú)法檢查出執(zhí)行錯(cuò)誤。

  實(shí)現(xiàn)ISynchronizeInvoke要求你使用一個(gè)代理來(lái)在后期綁定(late binding)中動(dòng)態(tài)地調(diào)用方法。每一種代理類型均提供DynamicInvoke()方法: public object DynamicInvoke(object[]
args);

  理論上來(lái)說(shuō),你必須將一個(gè)方法代理放到一個(gè)需要提供對(duì)象運(yùn)行的真實(shí)的線程中去,并使Invoke() 和BeginInvoke()方法中的代理中調(diào)用DynamicInvoke()方法。ISynchronizeInvoke的實(shí)現(xiàn)是一個(gè)非同一般的編程技巧,本文附帶的源文件中包含了一個(gè)名為Synchronizer的幫助類(helper class)和一個(gè)測(cè)試程序,這個(gè)測(cè)試程序是用來(lái)論證列表A中的Calculator類是如何用Synchronizer類來(lái)實(shí)現(xiàn)ISynchronizeInvoke的。Synchronizer是ISynchronizeInvoke的一個(gè)普通實(shí)現(xiàn),你可以使用它的派生類或者將其本身作為一個(gè)對(duì)象來(lái)使用,并將ISynchronizeInvoke實(shí)現(xiàn)指派給它。

  用來(lái)實(shí)現(xiàn)Synchronizer的一個(gè)重要元素是使用一個(gè)名為WorkerThread的嵌套類(nested class)。WorkerThread中有一個(gè)工作項(xiàng)目(work item)查詢。WorkItem類中包含方法代理和參數(shù)。Invoke()和BeginInvoke()用來(lái)將一個(gè)工作項(xiàng)目實(shí)例加入到查詢里。WorkerThread新建一個(gè).NET worker線程,它負(fù)責(zé)監(jiān)測(cè)工作項(xiàng)目的查詢?nèi)蝿?wù)。查詢到項(xiàng)目之后,worker會(huì)讀取它們,然后調(diào)用DynamicInvoke()方法。

posted on 2007-10-15 12:08 獨(dú)孤九劍 閱讀(211) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Learn articles
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品久久久久久久免费软件 | 欧美中文日韩| 久久久中精品2020中文| 亚洲欧美一区二区视频| 欧美精品成人在线| 欧美成人精品一区二区三区| 国产精品稀缺呦系列在线| 91久久夜色精品国产九色| 韩日欧美一区| 欧美亚洲系列| 欧美一区二区啪啪| 国产精品久久久久毛片软件| 亚洲人成在线影院| 亚洲伦理自拍| 欧美国产日韩二区| 欧美顶级少妇做爰| 一区二区三区在线观看国产| 欧美一区二区啪啪| 久久电影一区| 国产美女诱惑一区二区| 亚洲一区二区三区四区在线观看| 亚洲午夜女主播在线直播| 欧美激情在线有限公司| 最新成人av网站| 日韩视频在线观看| 欧美大尺度在线| 亚洲精品国产精品国产自| 亚洲精品无人区| 欧美日韩国产一中文字不卡| 日韩午夜av| 亚洲私人影院在线观看| 国产精品久久久久高潮| 在线视频欧美日韩精品| 午夜精彩视频在线观看不卡| 国产伦精品一区二区三区视频孕妇| 亚洲免费在线看| 久久久另类综合| 在线观看日韩一区| 欧美成人午夜影院| 日韩小视频在线观看专区| 亚洲小视频在线观看| 国产精品视频一区二区高潮| 午夜亚洲视频| 欧美v国产在线一区二区三区| 亚洲国产精品专区久久| 欧美国产专区| 亚洲一二三区在线| 久久综合给合久久狠狠色| 亚洲国产欧美一区二区三区丁香婷| 欧美va亚洲va香蕉在线| 亚洲免费成人av电影| 欧美亚洲自偷自偷| 在线观看欧美黄色| 欧美片第一页| 欧美在线网站| 亚洲人午夜精品| 欧美一区视频在线| 亚洲国产一二三| 国产精品久久久久国产a级| 久久精品国产欧美亚洲人人爽| 欧美成人有码| 亚洲欧美一区二区三区在线 | 一区二区三区自拍| 欧美精品一区在线| 性色一区二区三区| 亚洲欧洲一二三| 久久久久国色av免费观看性色| 亚洲人成7777| 国产在线国偷精品产拍免费yy| 欧美高清视频一区二区三区在线观看 | 欧美日韩国产精品一区二区亚洲| 亚洲午夜电影| 亚洲高清一二三区| 久久久久国产精品人| 日韩一级精品视频在线观看| 国产一区二区三区无遮挡| 欧美激情aⅴ一区二区三区| 欧美影院精品一区| 在线亚洲高清视频| 亚洲黄色尤物视频| 母乳一区在线观看| 久久精品国产久精国产思思| 亚洲调教视频在线观看| 最近中文字幕日韩精品| 国内精品伊人久久久久av一坑| 欧美日韩亚洲网| 欧美成人xxx| 久久深夜福利免费观看| 性欧美办公室18xxxxhd| 中文国产亚洲喷潮| 日韩午夜精品视频| 亚洲欧洲另类国产综合| 欧美电影免费观看高清| 久久亚洲不卡| 久久精品一区蜜桃臀影院| 亚洲欧美久久久| 亚洲一区二区av电影| 99在线精品观看| 99精品国产99久久久久久福利| 亚洲黄色av一区| 亚洲国产成人久久| 在线看国产一区| 精品电影一区| 悠悠资源网久久精品| 影音先锋日韩精品| 一区二区三区在线视频免费观看 | 夜夜嗨av色一区二区不卡| 亚洲黄页一区| 亚洲日韩欧美一区二区在线| 亚洲福利视频网站| 亚洲三级影片| 一区二区三区精品视频| 一区二区三区欧美日韩| 一区二区三区|亚洲午夜| 日韩午夜高潮| 亚洲欧美国产三级| 欧美一区二区性| 久久久久久久97| 欧美国产日产韩国视频| 欧美午夜久久久| 国产欧美欧美| 亚洲第一中文字幕| aa亚洲婷婷| 欧美在线3区| 美日韩精品视频免费看| 欧美激情一区二区三区四区| 亚洲狼人综合| 亚洲一区二区三区视频| 久久精品一区二区三区不卡| 麻豆精品视频在线观看视频| 欧美日韩黄色大片| 国产欧美日韩亚洲| 在线看无码的免费网站| 一区二区三区免费看| 久久精品99无色码中文字幕 | 久久国产精品一区二区三区四区 | 在线观看国产欧美| 正在播放亚洲一区| 久久精品夜色噜噜亚洲aⅴ| 亚洲成人在线视频播放 | 欧美激情自拍| 国产拍揄自揄精品视频麻豆| 在线成人h网| 亚洲综合首页| 美女露胸一区二区三区| 亚洲精品乱码久久久久久| 香蕉精品999视频一区二区| 欧美大片在线看| 国产一区二区三区av电影| 日韩一级二级三级| 久久精品日产第一区二区| 亚洲黄色小视频| 欧美在线首页| 国产精品乱码久久久久久| 亚洲福利免费| 午夜欧美不卡精品aaaaa| 欧美激情性爽国产精品17p| 亚洲一区国产一区| 欧美老女人xx| 在线观看国产一区二区| 欧美亚洲免费高清在线观看| 亚洲第一在线综合网站| 欧美在线视频观看| 国产精品久久久久久久久久久久久久| 1024精品一区二区三区| 欧美一区亚洲一区| 99精品免费网| 欧美激情综合| 1024精品一区二区三区| 久久精品国产亚洲a| 亚洲桃花岛网站| 欧美日韩国产成人在线| 亚洲黄色成人| 蜜臀久久99精品久久久久久9| 亚洲综合国产激情另类一区| 欧美高清视频一区| 亚洲国产天堂久久综合| 老司机精品导航| 欧美中文在线视频| 国产裸体写真av一区二区| 亚洲综合日本| 一区二区免费在线播放| 欧美日韩三级视频| 一本久久综合亚洲鲁鲁| 亚洲国产精品成人久久综合一区| 久久久亚洲国产美女国产盗摄| 国产日韩欧美在线| 欧美综合国产精品久久丁香| 亚洲一区二区三区欧美| 国产精品日韩电影| 午夜在线视频观看日韩17c| 亚洲私人影吧| 国产精品一区二区欧美| 欧美一区二区黄| 欧美在线观看视频在线| 国户精品久久久久久久久久久不卡 | 亚洲综合日本| 亚洲欧美日韩国产综合在线| 国产精品自拍在线| 久久视频一区|