建水老家紹康杯全國攝影的大賽作品展全國公映_紅外線烤爐

※票選推薦煮婦最愛手壓封口機,省荷包不犧牲品質

意信臻專營:封口機、各式包裝機械、專業製造、全省批發零售

題圖:納本良作品《東門夜景·建水東門》朝陽樓即建水東門城樓,雄踞建水縣縣城中心,成於明洪武二十二年(1389年)至今六百餘年,是滇南重鎮建水歷史悠久的主要標誌之一,祖國邊陲古老重鎮的象徵。  

3月1日雲南.紅河訊(本報記者:納本良,通訊員:季增壽、朱寶英),本報從建水老家紹康杯全國攝影大賽組委會和中央数字電視攝影頻道獲悉,以展示人文建水,攝影天堂厚重、多彩的民俗、民族、人文、歷史文化底蘊,展示“建水紫陶”神韻,兼顧建水的其他自然、人文內涵的建水老家紹康杯全國攝影大賽作品展將通過中央数字電視攝影頻道向全國公映。

建水,是雲南省紅河哈尼族彝族自治州下轄的縣之一,該縣位於雲南省南部紅河北岸,氣候宜人,建水距省會昆明二百餘千米,動車、高速公路都通達這裏,建水有比天安門歷史還久的朝陽樓、有中國現存規模第二大的文廟、這裏的紫陶位列中國四大名陶,中國第一條民營鐵路在這裏仍在運營,這裏的烤豆腐登上了紀錄片《舌尖上的中國》。

建水歷史始於西漢時期,歷經二千多年,留下了許多充滿深厚文化意韻的建築物,古代寺廟、祠庵和樓台亭閣多達50餘處,被譽為“古建築博物館”和“民居博物館”,還有充滿濃郁地方民族特色的建水小調,看的、吃的、聽的各具特色,讓人流連忘返。

在建水縣人民政府和建水紫陶非遺傳承人陳紹康大師的支持下,建水老家紹康杯全國攝影大賽得以實現,中央数字電視攝影頻道紅河站組織了二百餘人的攝影家前往創作,厚重、多彩的民俗、民族、人文、歷史文化底蘊,“建水紫陶”神韻、勤勞、智慧的建水人民,為大賽提供了豐富的創作元素,現在讓我們跟隨他們的鏡頭,一覽人文建水,大美建水、攝影天堂的精美映象!

播出頻道:攝影頻道

播出時間:

3月3日(星期日)20:00首播  

3月3日(星期日)22:30  

3月4日(星期一) 9:20、12:50重播。 

下周內,還會由系統擇機插播數次,以便讓更多人看到。

收看方式:

紅河地區:廣電網160頻道

其他地區請諮詢當地電視運營商  

全球:中星5號

中央数字電視攝影頻道衛星調試參數:本振頻率5150,下行頻率4020,符號率27500,視頻PID 0520,音頻PID 0730,極化方式垂直,在中星6B衛星接收機上有這個頻道,如果沒有預設,可以輸入以上參數觀看。

紅河大影家會在紅河各社交媒體(微信、QQ、新媒體)延後播出。

參加展播的攝影家名單(按照漢語拼音語音為序)

白章磊、蔡永元、曹祖德、車洪國、方   俊、郭依林、后建光、呼延紅、黃    磊、黃進雄、季增壽、蔣發珍、金    濤

金家茂、雷學軍、李   東、李   林、李淑萍、李穎凡、梁鑫偉、劉    迪、劉    曙、劉炳祥、劉湖榮、劉曉林、盧維前

盧小霞、盧怡昆、陸小兵、馬   明、馬俊勇、馬啟堂、毛鳳鳴、苗文英、納本良、納建忠、鷗    洋、普學和、賽雲鶴

石晨華、史   遠、孫成林、孫國玉、王   超、王    偉、王    秀、王   英、王    瑛、王建華、王立娟、王泰恆、王玉華

王仲璋、吳   煒、武德剛、向玉明、肖代成、肖建華、肖琨偉、謝豐成、謝雲貴、徐永健、陽和辛、楊成文、楊俊鵬

楊文橋、楊   勇、楊忠偉、張   青、張    澤、張進發、張茂恆、張曉兵、張曉梅、張忠文、趙家喜、趙永勝、趙雲祥

周    暢、周一姝、朱其晦等

建水老家紹康杯全國攝影大賽作品電視展播編導人員

總編導;納本良

副總編導:王   偉、盧維前

編導:賴慶國、金曉弟、張曉梅、楊   品、楊成文、梁鑫偉、李穎凡

劇務:季增壽、朱寶英、張忠文、趙   剛

本次建水老家紹康杯全國攝影大賽作品電視展播,將播出133組作品,包含260個創作元素,是從近四百幅獲獎作品、榮譽作品中選出,這是對大美建水、大美紅河的禮讚,又是對熱愛建水、熱愛紅河的攝影家的褒獎和點贊。

大賽的頒獎典禮計劃在三月份在建水隆重進行,並有頒獎、抽獎、表彰等多項內容。

屆時,歡迎社會各界以各種方式加盟頒獎盛典,助力本次大賽,點贊建水老家。

領略中華智慧,感悟人生之道,以“尋找最鮮活的社會榜樣,記錄最動人的中國精神”。

紅河站的辦公地點在雲南省紅河哈尼族、彝族自治州中部城市開遠,有“開拓荒遠邊疆”之意,又有“四面伸開連接廣遠”之意,紅河站敞開心扉歡迎全國影友的加入其中,來吧!朋友!

開啟視覺窗口,盡享大千世界,攝影頻道用想象擦亮光影,用光影記錄影像!

※多功能滑鼠墊、多用途卡套、全客製贈品節慶促銷活動開跑中  

表面採用環保霧面PP材質。
印刷後貼上珠光膜,使滑鼠墊顏色更為精緻漂亮,底層採用止滑顆粒膠,撕開保護膜後滑鼠墊可平貼於桌面,簡單又好用的辦公室小物

讓感動常在!為華夏增添正能量!

大美建水、大美紅河、攝影的天堂!紅河有你更精彩!

建水老家 紹康杯全國攝影的大賽作品展公映作品選:

楊忠偉《建水龍窯》組照之一

賽雲鶴《包容》

王   英《龍窯》

周   暢《俯闞臨安》組照之一

張進發《雙龍橋》

鷗   洋《入神》

張   澤《古橋風雲》

呼延紅《古城紫陶手藝人陳紹康大師及其作品》組照之一

李淑萍《精湛的紫陶工藝》組照之一

肖琨偉《美女與紫淘》

梁鑫偉《相得益彰》

盧維前《豐收的喜悅》

王   偉《江山如畫》

楊成文《建水“碼”上改變生活》組照之一

張曉梅《一眼井》

納本良《夢幻之橋》

圖片說明:紅河大影家。納本良作品,圖片為建水雙龍橋。紅河大影家,中央数字電視攝影頻道紅河站致力於邁向專業化發展的攝影引領團隊。

本站聲明:網站內容來源http://www.societynews.cn/html/xw/sh/,如有侵權,請聯繫我們,我們將及時處理

※家庭、朋友聚會,享受輕鬆烤肉必備紅外線烤爐NO.1

統烤爐使用木頭、煤炭燃燒加熱。現代烤爐則有多功能,使用分別為電熱或天然氣,烤爐分單層、雙層和三層型式,各層獨立控制,可同時使用,也可單層單烘爐分單層、雙層和三層型式,各層獨立控制,一般都有自動恆溫系統。

2月中國好人榜發布_ 堆高機

※幫你考照過關,堆高機裝卸操作教學影片大公開 !

上千家公司找到最適合的堆高機搬運方案,專業的規劃與完善的售後服務,讓孚克力堆高機與各大知名廠商建立長期合作。

2月份,網上“我推薦我評議身邊好人”活動共收到網民舉薦的好人好事線索176萬餘條,頁面瀏覽量超過3600萬。經網上展示宣傳、網友點贊評議,傳承大愛家風、共簽器官捐獻書的張俠、張曉杏、張三貞、張磊四姐妹,練就精湛技藝、填補技術空白的自動化工程師張世友,放棄高薪回鄉創業盡孝的女白領王霞,義務掃街35年的好村民羅玉蓮,春節期間勇救墜江轎車司機的90后小伙梅源,跳入冰窟救出落水老人的輔警熊劍等103人榮登中國好人榜。平民英雄、凡人善舉成為網上熱點,溫暖了社會。

SMD electronic parts counting machine

累積多年設計生產 Embossed Carrier Tape承載帶的實際經驗,專為電子主、被動零件設計、包裝、製造、改良承載帶、奠定了良好基礎

  3月1日,中央文明辦在江蘇徐州舉辦2月中國好人榜發布儀式暨全國道德模範與身邊好人交流活動,通過中國文明網、人民網、新華網、光明網、央視網、央廣網及騰訊視頻、新浪微博、快手、鬥魚等直播平台進行網絡直播,觀看網友超過4300萬人次。

本站聲明:網站內容來源http://www.societynews.cn/html/xw/sh/,如有侵權,請聯繫我們,我們將及時處理

※業界餐飲設備NO1.嘉冠烤爐

電烤箱是利用電熱元件所發出的輻射熱來烘烤食品的電熱器具,利用它我們可以製作烤雞、烤鴨、烘烤麵包、糕點等。根據烘烤食品的不同需要,電烤箱的溫度一般可在50-250℃範圍內調節。

國網北京電力 持續發力優化營商環境_L夾

※全自動飲水機與一般飲水機差異在哪?

推薦各種冰溫熱開飲機飲水機:台銀採購契約飲水機、日本進口電解水機系列、落地型飲水機

※專業客製化禮物、贈品設計,辦公用品常見【L夾】搖身一變大受好評!!

採用PVC0.2白色軟皮料印製,4色印刷加上表層防刮油墨,另也可選表層上亮膜。

  2019年國網北京市電力公司將持續優化電力營商環境工作舉措,進一步深化“三零”服務,創新推出“三省”服務,全力打造國際一流、國內領先的“獲得電力”服務,推動北京地區電力營商環境持續優化。
  在進一步深化“三零”服務方面,國網北京電力今年新推出三項改革創新。一是線上服務渠道更加豐富。“三零”服務合同可在線上电子化簽訂,客戶通過“掌上電力”APP報裝后,可在線同步簽訂《供用電合同》。电子化后,減少了線下溝通環節,服務效率明顯提升。二是業務辦理時間進一步壓縮。在北京市委、市政府的決策和市城市管委會的大力推進下,低壓項目掘路審批手續辦理由原來的“一串四並”改為“五並”,辦理時長由15天壓縮至5天,小微企業接電時長進一步縮短。在此基礎上,電力公司通過客戶回訪、第三方評價等機制,主動接受客戶監督,及時回應客戶訴求,客戶接電服務評價渠道更加暢通。三是電費透明度進一步提升。客戶可通過“掌上電力”APP、95598網站等線上渠道查詢電量電費。同時,市發展和改革委規定“在電價調整前一個月向客戶公示告知”,電費電價政策更加透明。
  國網北京電力深入分析客戶需求,針對10千伏臨時用電客戶面臨的手續多、資料多、時間長、成本高等問題,創新推出臨時用電“省時、省力、省錢”的“三省”服務,打破了之前由用電客戶作為實施主體的工程模式,為客戶提供從報裝接電到後期維護的全過程服務,讓客戶切實感受到“三省”服務的便利、快捷和經濟。
  ——省力:客戶可通過“掌上電力”企業版APP、營業廳等渠道自願選擇“三省”服務產品,電力公司安排客戶經理全程上門服務,提供菜單式、套餐式服務產品,客戶可通過用電容量、變壓器型號和外電源敷設方式等需求選擇服務產品。
  ——省時:通過科學編製典型設計、超市化物資採購等措施,大大壓縮了設計、招標和設備生產周期,將臨時用電平均接電周期降至20個工作日以內。
  ——省錢:利用共享理念,實現變壓器等臨時用電設備在多個客戶之間共享,服務期滿后及時拆除回收、檢修試驗,並再次利用。客戶無需重新購置設備,無需自行維護,最大程度減少客戶重複投資。
  自臨時用電“三省”服務推出以來,國網北京電力已受理“三省”服務報裝項目31個,送電23個。已送電的項目平均接電時長18天,累計為客戶節省投資約500萬元,節省比例約30%。

本站聲明:網站內容來源http://www.societynews.cn/html/xw/sh/,如有侵權,請聯繫我們,我們將及時處理

※選擇示波器的10 項考量因素

示波器是一種能夠顯示電壓訊號動態波形的電子測量儀器。它能夠將時變的電壓訊號,轉換為時間域上的曲線,原來不可見的電氣訊號

公益短片《家國與邊關》走進全國院線_組合外燴烤爐

※高價位跟低價位的示波器又有何差異?

示波器是一種能夠顯示電壓訊號動態波形的電子測量儀器。它能夠將時變的電壓訊號,轉換為時間域上的曲線,原來不可見的電氣訊號

沒有飛機坦克,沒有炮火硝煙,普通軍人的日常生活同樣打動人心。由軍隊相關部門拍攝的邊防軍人公益短片《家國與邊關》,自3月1日起作為電影貼片登陸全國1萬多家影院。這部短片時長45秒,取材自國防部年前發布的同名視頻。

  黨的十九大報告指出,“讓軍人成為全社會尊崇的職業”。這是習主席對新時代革命軍人巨大的鼓舞和激勵。要把習主席這一重要指示落到實處,需要多角度、多方位展示軍人群體,讓人民充分了解軍人。據軍隊相關部門負責人表示,《家國與邊關》走進電影院是一次全新的探索。

※必買推薦!組合外燴烤爐全台最便宜都在這!

烤爐是傳統家庭廚房的常見設備,一般為臥式。在飛機上也常設有烤箱,以加熱飛機餐。

  《家國與邊關》講述了在神仙灣、河尾灘、紅其拉甫等哨所邊關的邊防官兵奉獻青春、衛國戍邊的感人故事。此次,相關部門將“發布台平移到電影院”,將軍人的奉獻呈現在億萬觀眾面前,對大眾進行“潤物細無聲”的國防教育,旨在讓更多人了解到“青春不只是眼前的瀟洒,也有家國與邊關”。

  此前,這部公益短片完整版已在去年12月27日國防部例行記者會上播放,並在微信公眾號、微博等網絡平台同步發布。“負重前行的青春,更值得我們去愛戴和敬仰”“向保家衛國的人民子弟兵致敬,他們是最可愛的人”……網友的留言不僅表達了對視頻短片的認可,而且折射出我軍新聞發布工作創新實踐的成果。(呂德勝 李姝睿)

本站聲明:網站內容來源http://www.societynews.cn/html/xw/sh/,如有侵權,請聯繫我們,我們將及時處理

CCD Taping Machine

包裝設計實際上涵蓋了多種設計範疇,需要高度設計專業,
以酒為例,酒瓶上的標籤設計是包裝設計的一種,需考量美觀與形塑產品特色提供充足資訊等,至於酒的外盒,提袋等,同樣是包裝設計的範疇,但更必須思考運送、保護、送禮、便利性與價值感等不同層面之問題。

新華社兩會新聞報道發稿中心啟用_示波器

自動旋轉烤玉米機比價站,幫你找好康~

烤箱是一種密封的用來烤食物或烘乾產品的電器,分為家用電器和工業烤箱。家用烤箱可以用來加工一些麵食。工業烤箱,為工業上用來烘乾產品的一種設備,有電的、有瓦斯的,又叫烤爐、烘乾箱等。

十三屆全國人大二次會議和全國政協十三屆二次會議分別於3月5日和3日在北京召開。新華社設在人民大會堂的兩會新聞報道發稿中心於1日正式啟用。

作為國家通訊社,今年兩會期間,新華社將以中、英、法、西、俄、阿、葡、日8種語言和文字、圖片、音視頻、報刊、網絡新媒體等形式,為海內外用戶和受眾提供全方位的新聞信息服務。

示波器鮮為人知的使用技巧?

一個典型的示波器通常是盒狀螢幕,有多個輸入連接,示波器至少包括探頭、顯示器和控制面板三部分

兩會期間,新華社將準確、及時播發兩會各項程序報道。文字報道將圍繞兩會主題,組織深度報道,全方位、多視角反映兩會全貌。圖片圖表報道播發生動鮮活的現場照片和簡明直觀的圖表漫畫。視頻直播線路將直播人大、政協發布會,總理、外長記者會,部長、代表、委員通道等活動,並利用新華社全球布局,會內會外聯動,在海外同時啟動現場報道。

今年兩會期間,新華社將繼續突出創新和融合理念,加大可視化產品供給。短視頻專線提供豎屏高清視頻節目。新媒體專線開設《微TED·履職故事:我在你身邊》等欄目,採用文字、圖片、動漫、動新聞等多媒體融合報道形式,提供符合新媒體用戶需求的新聞信息產品。全媒報道平台通過《新華全媒頭條》專欄,持續提供重點報道融媒體產品。此外,還將推出“辛識平”系列融媒體言論產品。

本站聲明:網站內容來源http://www.societynews.cn/html/xw/sh/,如有侵權,請聯繫我們,我們將及時處理

塑膠射出成型不良品原因及改善對策 !

隨著技術的不斷提升新觀念、新技術、新設備的不斷加入。

外交搭台 推介中國_飲水機

飲水機設備有哪些?

步步經營服務始終如一於雲嘉南地區,建立優質的飲水機之品牌

2月25日下午,在中國外交部藍廳,來自134個國家和國際組織的駐華使節、企業代表、專家學者以及中央和地方有關部門代表共500餘人,將目光聚焦在中國山西。

這是一場以“新時代的中國:山西新轉型共享新未來”為主題的全球推介活動。雲岡石窟、平遙古城,山西的歷史人文風景讓人讚歎;走轉型新路、與世界共享未來,山西的勃勃生機令人難忘。

“外交搭台、地方唱戲”。像這樣的省區市全球推介活動,是外交部服務地方的創新實踐。自2016年至今,外交部已舉辦了17場推介活動,擦亮地方的特色名片。

3年前的3月2日,在外交部的支持下,寧夏成為國內第一個舉辦全球推介活動的地區。此後,廣西、陝西、四川、貴州、雲南、安徽、吉林、內蒙古、江西、海南、河南、河北雄安新區、湖北、山東、黑龍江以及山西,接連舉辦推介活動。

推介活動上,各地的宣傳片都少不了介紹當地的自然、人文風光。這既容易吸引大家的目光、引發共鳴,又向世界宣傳了中國的歷史文化。

※客製專屬滑鼠墊、可愛造型L夾L型資料夾、透明證件套、手提袋,專業印刷設計廠商!

通過SGS環保認證,無毒無害 環保材質符合歐盟RoHs、REACH認證

參加過江西推介活動的尼泊爾駐華公使蘇希爾就對江西的山水風景印象最為深刻。他表示,尼泊爾與江西在旅遊資源上有相似之處,尼泊爾是旅遊勝地,江西也是旅遊大省,風光秀麗、遊客眾多。“現在我很想去江西看一看。”活動結束時,蘇希爾說。

在推介活動中,各地也着重強調自身富有創新精神的一面,以期與世界一同把握新機遇。

貴州是中國西部最具發展活力的省份之一,當地新興產業取得的成績讓人印象深刻。貴州的大數據电子信息、醫藥產業高速發展,精密鑄造、無人機、特大型橋樑、綠色農藥等技術達到國家或世界先進水平。

安徽在推介詞中介紹了本省的科技實力,包括在量子通信、信息显示、智能語音等領域所取得的一批全球領先的創新成果,例如科大訊飛公司連續10餘次獲得國際語音合成大賽冠軍。

江西在推介活動上強調當地承擔了國產大型客機C919多項機身製造關鍵技術研發及部分機身製造任務;硅襯底LED技術獲國家科學技術發明一等獎,依託“南昌光谷”加快產業化,讓“中國芯”點亮世界。

本站聲明:網站內容來源http://www.societynews.cn/html/xw/sh/,如有侵權,請聯繫我們,我們將及時處理

※使用真空封口機常見問題?

封口機用途廣泛,各產業袋類包裝,食品包裝、豆乾、喜餅、咖啡豆、咖啡粉掛耳包、鳳梨酥等等

跨出國門,全新國牌水芭莎席捲國際市場!_橡膠

※真空封口機該不該買?使用心得分享

各式封口機、包裝機械、客製化訂做、特殊改造

北京時間3月3日下午2:00整,輕奢生物護膚品牌水芭莎,即將榮耀上市,作為水芭莎品牌旗下的重磅單品——逆齡多肽精華液,與其同時正式上市。

水芭莎逆齡多肽精華液,從研發開始就備受外界關注。研發團隊歷時多年孜孜不倦的專研,終於突破了多肽技術難題,成功推出此款專為亞洲女性定製的精華液。水芭莎的上市,不僅彰顯了中國自主護膚品牌的崛起,更讓國際護膚市場刮目相看。

作為一個企圖進軍國際的野心團隊,水芭莎想做的不僅僅是國內自主護膚品牌,更要走出國門,讓國際市場都看到中國護膚新力量。

諸葛王堅在談到水巴莎品牌未來前景時明確指出,他們的最終目標一定是為全世界更多女性帶來健康的肌膚狀態,而不是僅僅服務於國內。

其實,水芭莎品牌早已在國際市場上打開了知名度,德國前總統武爾夫親自試用逆齡多肽精華液並推薦,稱讚其為市面上難得一見的好護膚品,即使在德國這樣相對發達的國家也能稱得上佳品,水芭莎憑藉其過硬的品質改變了國際對中國護膚品牌的原有觀念。

※特殊造型滑鼠墊去哪買?

滑鼠墊是滑鼠的好夥伴,可使滑鼠游標穩定滑順,多樣的材質

水芭莎深知亞洲女性的肌膚痛點,為此,科研團隊集中火力打造核心產品——逆齡多肽精華液,水芭莎品牌創始人諸葛王堅親自帶隊,多年如一日的研發活性多肽,放眼全球,尋覓珍稀抗老成分,12種珍貴黃金配比,配合尖端生物科技,穩准狠成分直達細胞,安全高效,改善肌膚難題。

逆齡多肽精華液作為水芭莎2019巔峰巨作,秉承科學護膚理念,打造醫美護膚新科技,改善八大肌膚問題,權威配方、珍稀成分,收縮毛孔舒緩祛痘,抵抗時間流逝,塑造年輕態,採用小分子玻尿酸,讓肌膚喝飽水,恢復年輕活力,活性多肽深入細胞,從根本上緊緻輪廓、深層修護。撫平歲月痕迹,重現優雅新生。

水芭莎承諾旗下產品無激素、無重金屬、無礦物油,安全不刺激,溫和零負擔。

水芭莎深知作為一個企業應有的責任,不僅僅是製造好產品,還要心懷社會、報答社會,這也是水芭莎品牌能在國際護膚市場佔有一席之地的重要條件之一,水芭莎不僅生產好產品,還致力於推動女性以美麗自信的心態面對生活。

作為水芭莎品牌成長的見證者,我們有理由相信:水芭莎不僅會成為我們民族驕傲的品牌,更會走出國門,擁抱世界。

用尖端科技與生物護膚相結合的產品特點吸引越來越多的海外消費者,佔據國際市場,常立於世界之林,為中國護膚品牌增光添彩!

本站聲明:網站內容來源http://www.societynews.cn/html/xw/sh/,如有侵權,請聯繫我們,我們將及時處理

※如何選購橡膠製品規格有哪些?

品質優益穩定,效率高成本低,並已獲得國內外大廠承認使用,品質合乎EIA國際標準, 此外也針對客戶端的需要代客Tape and Reel封裝服務。

觀察者模式_台北網頁設計

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

有別於一般網頁架設公司,除了模組化的架站軟體,我們的營業主軸還包含:資料庫程式開發、網站建置、網頁設計、電子商務專案開發、系統整合、APP設計建置、專業網路行銷。

觀察者模式簡述

觀察者(Observer)模式的定義:指多個對象間存在一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。這種模式有時又稱作發布-訂閱模式、模型-視圖模式,它是對象行為型模式。

觀察者模式結構與實現

 實現觀察者模式時要注意具體目標對象和具體觀察者對象之間不能直接調用,否則將使兩者之間緊密耦合起來,這違反了面向對象的設計原則。

觀察者模式主要結構如下:

  • 抽象主題(Subject)角色:也叫抽象目標類,它提供了一個用於保存觀察者對象的聚集類和增加、刪除觀察者對象的方法,以及通知所有觀察者的抽象方法。
  • 具體主題(Concrete    Subject)角色:也叫具體目標類,它實現抽象目標中的通知方法,當具體主題的內部狀態發生改變時,通知所有註冊過的觀察者對象。
  • 抽象觀察者(Observer)角色:它是一個抽象類或接口,它包含了一個更新自己的抽象方法,當接到具體主題的更改通知時被調用。
  • 具體觀察者(Concrete Observer)角色:實現抽象觀察者中定義的抽象方法,以便在得到目標的更改通知時更新自身的狀態。

uml圖如下:

 

 觀察者模式代碼實現如下:

/**
 * 抽象主題(被觀察角色)
 */
public abstract class Subject{
    //觀察者list集合(聚集對象)
    protected List<Observer> observerList=new ArrayList<Observer>();
    //註冊觀察者
    public void addObserver(Observer observer){
        observerList.add(observer);
    }
    //刪除觀察者
    public void removeObserver(Observer observer){
        if(observerList.contains(observer)){
            observerList.remove(observer);

        }
    }
    //通知觀察者
    public abstract void notifyObserver();
}

/**
 * 具體主題角色類(被觀察的類)
 */
public class ConcreteSubject extends Subject{
    @Override
    public void notifyObserver() {
        System.out.println("被觀察者發現變化了...");
        for(Observer observer:super.observerList){
            observer.update();
        }

    }
}

/**
 * 抽象觀察者
 */
public interface Observer {
    public void update();
}


/**
 * 具體觀察者類
 */
public class ConcreteObserver1 implements Observer {
    @Override
    public void update() {
        System.out.println("observe1 更新了");
    }
}

/**
 * 具體觀察者
 */
public class ConcreteObserver2 implements Observer {
    @Override
    public void update() {
        System.out.println("observer2 發生變更");
    }
}


/**
 * 客戶端測試類
 */
public class ObserverClient {
    public static void main(String[] args) {

        Subject subject=new ConcreteSubject();
        Observer observer1=new ConcreteObserver1();
        Observer observer2=new ConcreteObserver2();
        subject.addObserver(observer1);
        subject.addObserver(observer2);
        //具體主題發生變化通知觀察者。
        subject.notifyObserver();

    }
}

觀察者模式案例

1.利用觀察者模式設計一個程序,分析“人民幣匯率”的升值或貶值對進口公司的進口產品成本或出口公司的出口產品收入以及公司的利潤率的影響。

分析:。被觀察的抽象主題對象就是匯率Rate,以人民幣匯率RMBRate為具體主題。以公司Company為抽象觀察者,出口公司ExportCompany為具體的觀察者,進口公司ImportCompany為具體的觀察者,人民幣匯率(具體主題角色)升值時,進口公司(具體觀察者對象)的進口產品成本降低且利潤率提升,出口公司(具體觀察者對象)的出口產品收入降低且利潤率降低;當人民幣匯率貶值時,進口公司的進口產品成本提升且利潤率降低,出口公司的出口產品收入提升且利潤率提升。總而言之當主題角色匯率發生變化時,觀察者Company的利潤也相應發生變化。

uml圖如下:

 

 代碼實現如下:

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

日本、大陸,發現這些先進的國家已經早就讓電動車優先上路,而且先進國家空氣品質相當好,電動車節能減碳可以減少空污

/**
 * 抽象觀察者
 */
public interface Company {
    void update(int changeRate);
}

/**
 * 具體觀察者進口公司ExportCompany
 */
public class ExportCompany implements Company {
    @Override
    public void update(int changeRate) {
        if(changeRate>=0){
            System.out.println("人民幣匯率升值"+changeRate+"個基點,降低了進口產品成本,提升了進口公司利潤率");

        } else {
            System.out.println("人民幣匯率貶值"+(0-changeRate)+"個基點,提升了進口產品成本,降低了進口公司利潤率。");

        }
    }
}


/**
 * 具體觀察者進口公司importCompany
 */
public class ImportCompany implements Company {
    @Override
    public void update(int changeRate) {
        if(changeRate>=0){
            System.out.println("人民幣匯率升值"+changeRate+"個基點,降低了進口產品成本,提升了進口公司利潤率");

        } else {
            System.out.println("人民幣匯率貶值"+(0-changeRate)+"個基點,提升了進口產品成本,降低了進口公司利潤率。");

        }
    }
}

/**
 * 抽象主題角色
 */
public abstract class Rate {
    //觀察者company對象list集合
    protected List<Company> companyList=new ArrayList<Company>();
    //增加觀察者company對象
    public void addObserver(Company company){
        companyList.add(company);
    }
    //刪除觀察者company對象
    public void removeObserver(Company company){
        companyList.remove(company);
    }
    public abstract void change(int rateChange);
}

/**
 * 具體主題對象人民幣匯率RMBRate
 */
public class RMBRate extends Rate {

    @Override
    public void change(int rateChange) {
        for (Company company:super.companyList){
            company.update(rateChange);
        }
    }
}
/**
 * 匯率變化觀察者模式實現客戶端類
 */
public class RateClient {
    public static void main(String[] args) {
        //具體觀察對像進口公司
        Company importCompany=new ImportCompany();
        //具體觀察者對象出口公司
        Company exportCompany=new ExportCompany();
        //具體主題角色人民幣對象
        Rate rmbRate=new RMBRate();
        //增添觀察者對象
        rmbRate.addObserver(importCompany);
        rmbRate.addObserver(exportCompany);
        //匯率提升
        rmbRate.change(2);
        //匯率降低
        rmbRate.change(-3);
    }
}

2.事件監聽模式就是利用觀察者模式實現的,java的awt窗體程序就是用觀察者模式實現的,在軟件幵發中窗體程序,界面程序都是基於事件監聽模式實現。現在以awt的Button的點擊事件為例,來了解一下事件監聽模式。首先創建一個按鈕Button類(事件源對象,被觀察者對象),將按鈕點擊監聽器註冊在Button上,當用戶點擊按鈕時,會產生一個按鈕點擊事件 ButtonClickEvent,將點擊事件傳給按鈕點擊監聽器 ButtonClickListener,監聽器做出相應的動作。

uml圖如下:

 代碼實現如下:

/**
 * 自定義按鈕類,事件源對象
 */
public class Button {
    private String buttonName;

    protected List<Listener> listenerlist = new ArrayList<Listener>();
    //註冊監聽器
    public void addListener(Listener listener){
        listenerlist.add(listener);
    }
    //移除監聽器
    public void removeListener(Listener listener){
        listenerlist.remove(listener);
    }
    //點擊方法
    public void press(){
        ButtonClickEvent event=new ButtonClickEvent(this);
        for (Listener listener:listenerlist){
            listener.actionPerformed(event);
        }
    }

    public String getButtonName() {
        return buttonName;
    }

    public void setButtonName(String buttonName) {
        this.buttonName = buttonName;
    }
}

package cn.ck.observer.v4;


import java.util.EventObject;

/**
 * 按鈕點擊事件
 */

public class ButtonClickEvent extends EventObject {
   private Object source;
public ButtonClickEvent(Object source){ this.source=source; } } /** * 抽象監聽器 */ public interface Listener { public void actionPerformed(ButtonClickEvent event); } /** * 按鈕點擊監聽器 具體觀察者 */ public class ButtonClickListener implements Listener { @Override public void actionPerformed(ButtonClickEvent event) { Button button= (Button) event.getSource(); System.out.println(button.getButtonName()+"按鈕被點擊了..."); } } /** * 按鈕事件測試類 */ public class ButtonClient { public static void main(String[] args) { Button b1=new Button(); Listener listener=new ButtonClickListener(); b1.setButtonName("button1"); Button b2=new Button(); b2.setButtonName("button2"); b1.addListener(listener); b2.addListener(listener); b1.press(); b2.press(); } }

jdk的觀察模式通過 java.util.Observable 類和 java.util.Observer 接口定義的,只要實現它們的子類就可以編寫觀察者模式實例。

1. Observable類

Observable 類是抽象目標類,它有一個 Vector 集合,用於保存所有要通知的觀察者對象,下面來介紹它最重要的 3 個方法。

  1. void addObserver(Observer o) 方法:用於將新的觀察者對象添加到向中Vector集合(線程安全)。
  2. void notifyObservers(Object arg) 方法:調用Vector集合中的所有觀察者對象的 update。方法,通知它們數據發生改變。通常越晚加入向量的觀察者越先得到通知。
  3. void setChange() 方法:用來設置一個 boolean 類型的內部標誌位,註明目標對象發生了變化。當它為真時,notifyObservers() 才會通知觀察者。

2. Observer 接口

Observer 接口是抽象觀察者,它監視目標對象的變化,當目標對象發生變化時,觀察者得到通知,並調用 void update(Observable o,Object arg) 方法,進行相應的工作。

還是以上面匯率的例子為例,用jdk的抽象觀察者,抽象目標類實現觀察者模式,具體代碼如下:

/**
 * 具體主題對象人民幣匯率RMBRate
 */
public class RMBRate extends Observable{

    public void change (int rateChange) {
        //changed變成true
        super.setChanged();
        super.notifyObservers(rateChange);
    }
}


/**
 * 具體觀察者進口公司ExportCompany
 */
public class ExportCompany implements Observer{

    @Override
    public void update(Observable o, Object arg) {
        int changeRate= (int) arg;
        if(changeRate>=0){
            System.out.println("人民幣匯率升值"+changeRate+"個基點,降低了進口產品成本,提升了進口公司利潤率");

        } else {
            System.out.println("人民幣匯率貶值"+(0-changeRate)+"個基點,提升了進口產品成本,降低了進口公司利潤率。");

        }

    }
}

/**
 * 具體觀察者進口公司importCompany
 */
public class ImportCompany implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        int changeRate= (int) arg;
        if(changeRate>=0){
            System.out.println("人民幣匯率升值"+changeRate+"個基點,降低了進口產品成本,提升了進口公司利潤率");

        } else {
            System.out.println("人民幣匯率貶值"+(0-changeRate)+"個基點,提升了進口產品成本,降低了進口公司利潤率。");

        }

    }
}


/**
 * 匯率變化觀察者模式實現客戶端類
 */
public class RateClient {
    public static void main(String[] args) {
        //具體觀察對像進口公司
        Observer importCompany=new ImportCompany();
        //具體觀察者對象出口公司
        Observer exportCompany=new ExportCompany();
        //具體主題角色人民幣對象
        RMBRate rmbRate=new RMBRate();
        //增添觀察者對象
        rmbRate.addObserver(importCompany);
        rmbRate.addObserver(exportCompany);
        //匯率提升
        rmbRate.change(2);
        //匯率降低
        rmbRate.change(-3);

    }
}

觀察者模式優點與缺點

1.觀察者模式優點

  • 降低了目標與觀察者之間的耦合關係,兩者之間是抽象耦合關係。
  • 目標與觀察者之間建立了一套觸發機制。

2.觀察者模式缺點

  • 目標與觀察者之間的依賴關係並沒有完全解除,而且有可能出現循環引用(可以通過事件類引用一個目標對象解決這個問題)。
  • 當觀察者對象很多時,通知的發布會花費很多時間,影響程序的效率。

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

日本、大陸,發現這些先進的國家已經早就讓電動車優先上路,而且先進國家空氣品質相當好,電動車節能減碳可以減少空污

不可不知的輔助測試的Fiddler小技巧,Fiddler抓包工具使用詳解,利用Fiddler攔截接口請求並篡改數據,Fiddler使用過程中容易忽略的小技巧,Mock測試,結合Fiddler輕鬆搞定不同場景_包裝設計

※產品缺大量曝光嗎?你需要的是一流包裝設計!

窩窩觸角包含自媒體、自有平台及其他國家營銷業務等,多角化經營並具有國際觀的永續理念。

在以前的博文中,時常有分享Fiddler的一些使用技巧,今天再貼下。

Fiddler抓包工具使用詳解

利用Fiddler攔截接口請求並篡改數據

Fiddler使用過程中容易忽略的小技巧

Mock測試,結合Fiddler輕鬆搞定不同場景

以上這些,就是以前的一些實踐總結。今天,再來分享一個不可不知的小技巧,實際工作當中,是可以輔助自己完成測試的。

模擬弱網

相信大家在進行測試過程中,都會關注到弱網測試。web端是可以通過瀏覽器的開發者工具中的Network設置網絡數據,app端也可以通過切換網絡的形式來進行測試。

其實,Fiddler也是支持模擬弱網測試的。通過Fiddler設置后,web和app都可以一併模式。

固定延遲設置方式

啟動Fiddler工具>找到FiddlerScript頁簽>按m_SimulateModem搜索。

找到如下所示內容【限速函數】,修改參數即可:

修改代碼中的參數,將300修改為3000,也就是3S,如下:

if (m_SimulateModem) {
            // Delay sends by 300ms per KB uploaded.
            oSession["request-trickle-delay"] = "3000"; 
            // Delay receives by 150ms per KB downloaded.
            oSession["response-trickle-delay"] = "150"; 
        }  

此時,保存修改后的Script代碼即可,如下所示:

數據保存后,如何使其生效呢?按如下操作即可。

在Fiddler中,按如下路徑配置即可:Rules>Performance>Simulate Modem Speeds。

具體操作,如下圖所示:

此時,再刷新頁面,我們可以從Fiddler面板中的Time參數看出,每個接口的響應時間都延時3s,如下所示:

網絡延遲時間如何計算?

比如你要模擬上傳速度100KBps的網絡,那上傳延遲就是1KB/100KBps=0.01s=10ms,就改成10。

隨機延遲設置方式

我們從上述操作看出,配置限速參數后,每個接口都是固定的延遲時間。但實際使用場景中,這種情況是比較少的。基本上都是有時快,有時慢的情況。那是否可以設置隨機延遲呢?答案肯定是可以的。我們繼續來看。

我們依然在FiddlerScript頁簽中操作,加入如下代碼,代碼如下所示:

static function randInt(min, max) {
  return Math.round(Math.random()*(max-min)+min);
  }
  if (m_SimulateModem) {
  // Delay sends by 300ms per KB uploaded.
  oSession["request-trickle-delay"] = ""+randInt(1,2000);
  // Delay receives by 150ms per KB downloaded.
  oSession["response-trickle-delay"] = ""+randInt(1,2000);
  }  

保存修改后的代碼,並重新啟用配置即可。

模擬發包

測試過程中,想模擬一個接口請求,一般是通過Postman、Jmeter、soupUI,常用的是Postman。我們Fiddler能不能模擬接口請求呢?這個是可以的,我們來看。

我們切換到Composer頁簽,如下所示:

從圖中可知,是可以模擬很多種請求方式的。我們就來實際操作一番。

POST請求

我們先來操作個POST請求,選擇POST請求方式,填寫接口與參數如下:

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網動廣告出品的網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上她。

接口與參數填寫正確后,點擊右上角的Execute按鈕即可請求接口。我們來看下請求數據:

我們先來看請求頭,接口請求頭中的User-Agent參數,如下所示:

用戶代理來源是Fiddler,就是剛才我們通過Fiddler工具請求的數據。

我們再來看響應,接口請求成功,正常響應並獲取到token數據,如下所示:

GET請求

剛才操作的是POST請求,現在來看個GET請求。操作方式都一樣,將請求方式切換成GET,填寫接口與參數,並點擊Execute按鈕,配置如下所示:

我們依然來看接口數據,先看請求頭參數:

 

User-Agent參數依然是Fiddler,說明是從Fiddler工具中發出的請求。

再來看響應數據,如下所示:

以上就是通過Fiddler模擬請求POST和GET請求了,其他方式類似。

模擬併發

在我們測試中,也會關注到,一個接口同時請求多次,會不會產生錯誤,比如:重複數據。那這次就需要考慮併發情況了。

Fiddler工具依然還是支持該操作,具體如下:

我們先選中已抓取的任一接口,點擊右鍵,並選擇Replay>Reissue Sequentially,也可以快捷鍵【Shift + R】如下所示:

點擊后,會彈出如下彈框,設置請求次數,如下所示:

默認是5,那我們改成3,並點擊OK按鈕,來看界面,如下所示:

我們可以看到,同時請求了3次,簡單模擬了併發測試,但實際是不及Jmeter工具的,畢竟這個也只是模擬,而Jmeter要專業許多。

了解完了併發使用,但還有些其他參數沒有介紹,我們來了解下其他參數,說不準以後也有用途。如下所示:

  • Reissue Requests:重發選中的請求
  • Reissue Unconditinally:無條件重發選中的請求
  • Reissue and eidt:重發並編輯,會打開一個加了斷點的請求,可以進行請求和響應數據的修改
  • Reissue and verify:重發並驗證,重新發送請求,並驗證其請求結果,會自動加標識(背景顏色)
  • Reissue Sequentially:重發序列,打開一個數量設置界面,標識需要重發多少次請求
  • Reissue from Composer:重發並打開composer界面,可以編輯或發送
  • Revisit in IE:在IE上發起這個請求

問題總結

在使用Fiddler模擬請求發包時,有時會操作失敗,比如通過百度查詢數據,GET接口,有時Caching參數不帶private參數就響應了302,正常帶該參數,是可以響應成功的,如下所示:

不知為何會出現,不帶該參數的情況。有遇到的博友,望提點一二。

 

好了,今天的這三個Fiddler技巧,就分享到這了,個人覺得在實際測試過程中,這三個技巧還是有幫助的。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

上新台中搬家公司提供您一套專業有效率且人性化的辦公室搬遷、公司行號搬家及工廠遷廠的搬家服務

C# 根據BackgroundWorker異步模型和ProgressBar控件,自定義進度條控件_台中搬家

台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

前言

程序開發過程中,難免會有的業務邏輯,或者算法之類產生讓人能夠感知的耗時操作,例如循環中對複雜邏輯處理;獲取數據庫百萬乃至千萬級數據;http請求的時候等……
用戶在使用UI操作並不知道程序的內部處理,從而誤操作導致程序無響應,關閉程序等待影響體驗的情況,因此,在等待過程中提供友好的等待提示是有必要的,接下來
我們一起封裝一個自定義進度條控件!

主要使用技術(C#相關)

  • BackgroundWoker異步模型
  • ProgressBar控件
  • 泛型
  • 定時器 System.Timers.Timer

自定義控件開發

項目解決方案

  • BackgroundworkerEx : 自定義進度條控件工程
  • Test : 調用BackgroundworkerEx的工程(只是展示如何調用)

處理控件樣式

  • 新建一個ProgressbarEx名稱的 用戶控件

  • 添加Labal控件(lblTips),用於展示進度條显示的信息狀態

  • 添加一個PictureBox控件(PicStop),充當關閉按鈕,用於獲取用戶點擊事件,觸發關閉/終止進度條

  • 添加進度條ProgressBar控件(MainProgressBar)

  • 處理代碼如下:

  1. 進度條樣式為”不斷循環”,並且速度為50
  2. 該自定義用戶控件不展示在任務欄中
  3. 圖片控件被點擊事件——>設置當前屬性IsStop=true,指示過程終止;
  4. TipMessage屬性,用於設置進度條的信息
  5. SetProgressValue(int value) 設置進度條的Value屬性,使得在ProgressBarStyle.Marquee樣式中動畫平滑
  6. MouseDown/MouseUp/MouseMove這三個事件是用於拖動無邊框的用戶控件(代碼就不貼了)
public ProgressbarEx()
{
    InitializeComponent();

    MainProgressBar.Style = ProgressBarStyle.Marquee;
    MainProgressBar.MarqueeAnimationSpeed = 50;

    this.ShowInTaskbar = false;

    PicStop.Click += (s, eve) =>
    {
    IsStop = true;
    };

    this.MouseDown += CusProgressForm_MouseDown;
    this.MouseUp += CusProgressForm_MouseUp;
    this.MouseMove += CusProgressForm_MouseMove;
}

/// <summary>
/// Need Stop ?
/// </summary>
public bool IsStop { get; private set; } = false;

/// <summary>
/// TipMessage
/// </summary>
public string TipMessage { get; set; }

/// <summary>
/// TipMessage
/// </summary>
public string TipMessage
{
    get
    {
    return lblTips.Text;
    }
    set
    {

    lblTips.Text = value;
    }
}

/// <summary>
/// Set ProgressBar value ,which makes ProgressBar smooth
/// </summary>
/// <param name="value"></param>
public void SetProgressValue(int value)
{
    if (MainProgressBar.Value == 100) MainProgressBar.Value = 0;

    MainProgressBar.Value += value;

}

到現在,這個自定義進度條控件的樣式基本完成了.

功能邏輯處理

運行前所需

  • 定義BackgroundWorkerEx<T>泛型類,並且繼承於 IDisposable
    1. 釋放資源;
 		/// <summary>
        /// Dispose
        /// </summary>
        public void Dispose()
        {
            try
            {
                DoWork = null;
                RunWorkCompleted = null;
                WorkStoped = null;

                _mWorkerThread = null;
                _mWorker.Dispose();
                _mWorker = null;
                _mTimer = null;
            }
            catch (Exception){}
        }
  1. T用與異步處理的時候,傳遞T類型
  • 因為我們是通過.Net 的 BackgroundWorker異步模型來做的,所以我們理所當然定義相關的事件:
    1. 異步開始
    2. 異步完成
    3. 加上我們自定義擴展的異步停止
    4. ……報告進度事件在此進度條樣式中並不需要

我們先定義這四個事件所用到的參數,因為在BackgroundWorkerEx<T>泛型類中,我們還是使用BackgroundWorker來處理異步過程,因此我們定義的參數泛型類需要繼承原來的參數類型,並且在傳輸傳遞中,將原生BackgroundWorkerArgument,Result屬性轉成全局的泛型T,這樣我們在外部調用的時候,拿到的返回結果就是我們傳入到BackgroundWorkerEx<T>泛型類中的T類型,而不需要使用as進行轉換; 注:因為原生沒有停止相關事件,所以自定義異步停止的事件參數使用的是DoWorkEventArgs<T>

    public class DoWorkEventArgs<T> : DoWorkEventArgs
    {
        public new T Argument { get; set; }
        public new T Result { get; set; }
        public DoWorkEventArgs(object argument) : base(argument)
        {
            Argument = (T)argument;
        }
    }


    public class RunWorkerCompletedEventArgs<T> : RunWorkerCompletedEventArgs
    {
        public new T Result { get; set; }
        public RunWorkerCompletedEventArgs(object result, Exception error, bool cancelled) : base(result, error, cancelled)
        {
            Result = (T)result;
        }
    }

接着我們需要去定義事件,參數使用以上定義的泛型類

	public delegate void DoWorkEventHandler(DoWorkEventArgs<T> Argument);
        /// <summary>
        /// StartAsync
        /// </summary>
        public event DoWorkEventHandler DoWork;

        public delegate void StopEventHandler(DoWorkEventArgs<T> Argument);
        /// <summary>
        /// StopAsync
        /// </summary>
        public event StopEventHandler WorkStoped;

        public delegate void RunWorkCompletedEventHandler(RunWorkerCompletedEventArgs<T> Argument);
        /// <summary>
        /// FinishAsync
        /// </summary>
        public event RunWorkCompletedEventHandler RunWorkCompleted;
  • 定義全局的字段
    1. private BackgroundWorker _mWorker = null;異步操作必要;
    2. private T _mWorkArg = default(T);操作傳遞進來的參數類並且返回到外部
    3. private Timer _mTimer; 定時器檢測自定義進度條控件屬性IsStop是否為true,並且動態修改進度條消息
    4. private Thread _mWorkerThread = null;異步操作在該線程中,終止時調用About()拋出ThreadAbortException異常,用於標記當前是停止而不是完成狀態
    5. private int _miWorkerStartDateSecond = 0; 異步消耗時間(非必要)
    6. private int _miShowProgressCount = 0; 動態显示”.”的個數(非必要)
    7. private ProgressbarEx _mfrmProgressForm = null; 自定義進度條控件實例
        /// <summary>
        /// .Net  BackgroundWorker
        /// </summary>
        private BackgroundWorker _mWorker = null;

        /// <summary>
        /// Whole Para
        /// </summary>
        private T _mWorkArg = default(T);

        /// <summary>
        /// Timer
        /// </summary>
        private Timer _mTimer = null;

        /// <summary>
        /// WorkingThread
        /// </summary>
        private Thread _mWorkerThread = null;

        /// <summary>
        /// Async time sec
        /// </summary>
        private int _miWorkerStartDateSecond = 0;

        /// <summary>
        /// Async time dot
        /// </summary>
        private int _miShowProgressCount = 0;

        /// <summary>
        /// ProgressbarEx
        /// </summary
        private ProgressbarEx _mfrmProgressForm = null;

  • 定義全局屬性
  1. IsBusy 返回_mWorker的工作忙碌是否
  2. ProgressTip 自定義進度條控件显示內容
	/// <summary>
        /// Express Busy
        /// </summary>
        public bool IsBusy
        {
            get
            {
                if (_mWorker != null)
                {
                    return _mWorker.IsBusy;
                }
                return false;
            }
        }

        /// <summary>
        /// 進度條提示 默認: 正在加載數據,請稍後[{0}]{1}
        /// </summary>
        public string ProgressTip { get; set; } = "Elapsed Time[{0}]{1}";

**到現在,我們已經將必要的字段,屬性,樣式都處理完成!!! ** 接下來我們就要實現方法

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

台中搬家公司推薦超過30年經驗,首選台中大展搬家

方法實現

  • 異步工作事件,用法與BackgroundWorker一致,

    1. 如果調用處沒有註冊DoWork事件,則直接返回

    2. 將接受到的參數創建成泛型參數類

    3. 開線程,將異步操作放在該線程中操作,注意設置線程的IsBackground=true,防止主進程意外退出,線程還在處理

    4. 循環直到線程結束

    5. e.Result = Argument.Result;將結果賦予Result,在停止或者完成事件中可以獲取到結果

		/// <summary>
        /// Working
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (DoWork == null)
            {
                e.Cancel = true;
                return;
            }

            DoWorkEventArgs<T> Argument = new DoWorkEventArgs<T>(e.Argument);

            try
            {
                if (_mWorkerThread != null && _mWorkerThread.IsAlive)
                {
                    _mWorkerThread.Abort();
                }
            }
            catch (Exception)
            {
                Thread.Sleep(50);
            }

            _mWorkerThread = new Thread(a =>
            {
                try
                {
                    DoWork?.Invoke(a as DoWorkEventArgs<T>);
                }
                catch (Exception)
                {

                }
            });

            _mWorkerThread.IsBackground = true;
            _mWorkerThread.Start(Argument);

            //Maybe cpu do not start thread
            Thread.Sleep(20);

            //Wait.....
            while (_mWorkerThread.IsAlive)
            {
                Thread.Sleep(50);
            }
            e.Result = Argument.Result;
        }
  • 異步完成/停止

    當線程停止拋出異常(catch但是不處理)/線程完成時會進入異步完成事件

    1. 完成后,將自定義進度條控件實例關閉,釋放
  1. 將全局的BackgroundWorker實例_mWorker相關事件取消註冊,並且檢查線程情況
  2. 感覺線程情況,如果線程狀態為ThreadState.Aborted意味着線程被停止了,調用停止事件,否則調用完成事件
	  /// <summary>
      /// Completed
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void Worker_RunWorkCompleted(object sender, RunWorkerCompletedEventArgs e)
      {
          try
          {
              if (_mfrmProgressForm != null)
              {
                _mfrmProgressForm.Close();
                  _mfrmProgressForm.Dispose();
                _mfrmProgressForm = null;
              }

                if (_mWorker != null)
                {
                    _mWorker.DoWork -= Worker_DoWork;
                    _mWorker.RunWorkerCompleted -= Worker_RunWorkCompleted;

                    try
                    {
                        if (_mWorkerThread != null && _mWorkerThread.IsAlive) _mWorkerThread.Abort();
                    }
                    catch (Exception) { }
                }

              //In timer, When stop progress will make thread throw AbortException
              if (_mWorkerThread != null && _mWorkerThread.ThreadState == ThreadState.Aborted)
            {
                  WorkStoped?.Invoke(new DoWorkEventArgs<T>(_mWorkArg));
              }
              else
              {
                  RunWorkCompleted?.Invoke(new RunWorkerCompletedEventArgs<T>(e.Result, e.Error, e.Cancelled));
              }
          }
          catch (Exception ex)
          {
              throw ex;
          }
      }
  • 線程開始

    1. 檢查消息提醒內容 , {0}{1}同於显示異步耗時和”..”的個數
    2. 在定時器執行方法中,檢查_mfrmProgressForm.IsStop是否為true,這個屬性標誌是否被停止;true則拋出異常
    3. _mfrmProgressForm不為Null則不斷修改當前的內容提醒,友好化,實際可以按需處理
    		  /// <summary>
            /// Timer Start 
            /// </summary>
            private void StartTimer()
            {
                //Check user ProgressTip
                if (!ProgressTip.Contains("{0}"))
                {
                    ProgressTip += "...Elapsed Time{0}{1}";
                }
    
                if (_mTimer != null) return;
    
                //On one sec 
                _mTimer = new Timer(1000);
                _mTimer.Elapsed += (s, e) =>
                {
                    //progress and it's stop flag (picture stop)||  this stop flag
                    if (_mfrmProgressForm != null && _mfrmProgressForm.IsStop)
                    {
                        if (_mWorker != null)
                        {
                            try
                            {
                                if (_mWorkerThread != null && _mWorkerThread.IsAlive)
                                {
                                    if (_mTimer != null && _mTimer.Enabled)
                                    {
                                        _mTimer.Stop();
                                        _mTimer = null;
                                    }
                                    _mWorkerThread.Abort();
                                }
                            }
                            catch (Exception) { }
                        }
                    }
    
                    if (_mfrmProgressForm != null)
                    {
                        //Callback 
                        _mfrmProgressForm.Invoke(new Action<DateTime>(elapsedtime =>
                        {
                            DateTime sTime = elapsedtime;
    
                            //worked time
                            _miWorkerStartDateSecond++;
                            if (_mfrmProgressForm != null)
                            {
                                _mfrmProgressForm.SetProgressValue(_miWorkerStartDateSecond);
                            }
    
                            //.....count
                            _miShowProgressCount++;
    
                            if (_miShowProgressCount > 6)
                            {
                                _miShowProgressCount = 1;
                            }
    
                            string[] strs = new string[_miShowProgressCount];
    
                            string ProgressStr = string.Join(".", strs);
    
                            string ProgressText = string.Format(ProgressTip, _miWorkerStartDateSecond, ProgressStr);
    
                            if (_mfrmProgressForm != null)
                            {
                                _mfrmProgressForm.TipMessage = ProgressText;
                            }
                        }), e.SignalTime);
                    }
                };
    
                if (!_mTimer.Enabled)
                {
                    _mTimer.Start();
                }
            }
    
  • 最後一步:異步開始BackgroundWorker用法一致,只是在最後開始了定時器和進度條控件而已

    /// <summary>
            /// Start AsyncWorl
            /// </summary>
            /// <param name="Para"></param>
            public void AsyncStart(T Para)
            {
                //if workeven is  null ,express user do not regist event
                if (DoWork == null)
                {
                    return;
                }
    
                _miWorkerStartDateSecond = 0;
                _miShowProgressCount = 0;
    
                //init
                if (_mWorker != null && _mWorker.IsBusy)
                {
                    _mWorker.CancelAsync();
                    _mWorker = null;
                }
    
                _mWorker = new BackgroundWorker();
    
                //create progressbar
                _mfrmProgressForm = new ProgressbarEx();
    
                //add event
                _mWorker.DoWork += Worker_DoWork;
                _mWorker.RunWorkerCompleted += Worker_RunWorkCompleted;
    
                _mWorker.WorkerReportsProgress = true;
                _mWorker.WorkerSupportsCancellation = true;
    
                //Set Whole Para
                _mWorkArg = Para;
    
                _mWorker.RunWorkerAsync(Para);
                //Start timer
                StartTimer();
    
                _mfrmProgressForm.StartPosition = FormStartPosition.CenterParent;
                _mfrmProgressForm.ShowDialog();
            }
    

到這裏,整個的進度條控件已經完成了!

調用

  • 定義一個參數類
	/// <summary>
    /// Para Class
    /// </summary>
    public class ParaArg
    {
        public DataTable Data { get; set; }
        public string Msg { get; set; }
        public Exception Ex { get; set; }
    }
  • 定義全局的幫助類BackgroundWorkerEx<ParaArg> workHelper = null;
  • 調用
				if (workHelper != null || (workHelper != null && workHelper.IsBusy))
                {
                    workHelper.Dispose();
                    workHelper = null;
                }
                if (workHelper == null)
                {
                    workHelper = new BackgroundWorkerEx<ParaArg>();
                }

                workHelper.DoWork += (eve) =>
                {
                    ParaArg args = eve.Argument;

                    try
                    { 
                        //ToDo  like Thread.Sleep(20000);
                        Thread.Sleep(10000);
                        args.Msg = "...this is bussiness code result";
                        throw new Exception("");
                    }
                    catch (Exception ex)
                    {
                        args.Ex = ex;
                    }
                    finally
                    {
                        eve.Result = args;
                    }

                };
                workHelper.RunWorkCompleted += (eve) =>
                {
                    if (eve.Error != null)
                    {
                        //get .net backgroundworker exception;
                        //handle this exception;
                        //return ?
                    }

                    //get your para result
                    ParaArg x = eve.Result;
                 
                    if (x.Ex != null)
                    {
                        //get your bussiness exception;
                        //handle this exception;
                        //return ?
                    }

                    //finially get your need;
                    //MayBe to do some UI hanlde and bussiness logical
                    string sReusltMsg = x.Msg;
                };

                workHelper.WorkStoped += (eve) =>
                { 
                    //if stoped ! it means no error;
                    //just get what you want; 
                    ParaArg x = eve.Result as ParaArg;

                    btnBegin.Enabled = true;
                };

                //參數
                ParaArg arg = new ParaArg()
                {
                    Msg = "Msg"
                };

                workHelper.AsyncStart(arg);

最後

其實不管是封裝的過程,還是調用,可以說完全就是BackgroundWorker的方式,所以很多BackgroundWorker相關的地方我都沒有很詳細的去說明;只要看看這個異步模型,就能夠很好理解!大家有空也可以實現以下,有問題也可以詳細,我比較喜歡交流技術~~~

還有一點就是這個解決方案已經放上Github上了,歡迎大家拉下來用

  • GitHub地址 歡迎star/fork

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司