![基于云存儲實(shí)現(xiàn)用Windows Azure Storage增_第1頁](http://file4.renrendoc.com/view/af15ef94961ab33c67744d34a2aff6e5/af15ef94961ab33c67744d34a2aff6e51.gif)
![基于云存儲實(shí)現(xiàn)用Windows Azure Storage增_第2頁](http://file4.renrendoc.com/view/af15ef94961ab33c67744d34a2aff6e5/af15ef94961ab33c67744d34a2aff6e52.gif)
![基于云存儲實(shí)現(xiàn)用Windows Azure Storage增_第3頁](http://file4.renrendoc.com/view/af15ef94961ab33c67744d34a2aff6e5/af15ef94961ab33c67744d34a2aff6e53.gif)
![基于云存儲實(shí)現(xiàn)用Windows Azure Storage增_第4頁](http://file4.renrendoc.com/view/af15ef94961ab33c67744d34a2aff6e5/af15ef94961ab33c67744d34a2aff6e54.gif)
![基于云存儲實(shí)現(xiàn)用Windows Azure Storage增_第5頁](http://file4.renrendoc.com/view/af15ef94961ab33c67744d34a2aff6e5/af15ef94961ab33c67744d34a2aff6e55.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
基于云存儲實(shí)現(xiàn)用WindowsAzureStorage增基于云存儲實(shí)現(xiàn)用WindowsAzureStorage增強(qiáng)應(yīng)用程序的引擎概述:您可以在云中運(yùn)行后臺進(jìn)程。KevinHoffman和NateDudek使用購物車示例演示如何構(gòu)建應(yīng)用程序引擎,以及如何使用AzureStorage實(shí)現(xiàn)異步消息傳送和處理。開發(fā)人員容易依賴其有形的、可感知的基礎(chǔ)結(jié)構(gòu),就像其是“安全毛毯”。他們知道如何使用、如何操作,如果出現(xiàn)問題,他們知道問題出在哪兒。而這通常會成為開發(fā)人員采用更新的技術(shù)(例如云計算)的障礙。心存懷疑的開發(fā)人員提出的最大疑問之一是他們?nèi)绾卧谠浦欣^續(xù)運(yùn)行后臺進(jìn)程,即他們的引擎如何繼續(xù)運(yùn)行。本文旨在通過向您演示如何構(gòu)建應(yīng)用程序引擎以及使用WindowsAzureStorage實(shí)現(xiàn)異步消息傳送和處理來為您揭開云中缺乏后臺處理的神秘面紗。為了證明開發(fā)人員可以拋開其有形的基礎(chǔ)結(jié)構(gòu)這條“安全毛毯”并將其應(yīng)用程序引擎置于云中,我們將介紹如何實(shí)現(xiàn)電子商務(wù)應(yīng)用程序的一個小型子集HollywoodHackers,您可以從中購買到Hollywood用于完全忽略物理法則和過時的常識的所有神奇技術(shù)。我們將介紹的兩個主要方案如下:將異步文本消息(“toasts”)發(fā)送給使用該應(yīng)用程序的用戶,以通知他們發(fā)生的重要事件(如已提交他們的購物車)或在員工之間發(fā)送消息。此方案使用WindowsAzureQueue、WindowsAzureTable和WindowsAzure工作者角色。此方案使用WindowsAzureQueue和WindowsAzure工作者角色將購物車提交給執(zhí)行引擎。使用隊(duì)列存儲進(jìn)行內(nèi)部應(yīng)用程序消息傳送在介紹具體的方案之前,我們需要先介紹一些有關(guān)WindowsAzureQueue的基礎(chǔ)知識。云中的隊(duì)列與傳統(tǒng)的.NET應(yīng)用程序中的隊(duì)列的運(yùn)行方式不太一樣。在處理AppDomain中的數(shù)據(jù)時,您知道該數(shù)據(jù)只有一份,它完整地位于單一托管進(jìn)程中。而在云中,您的一部分?jǐn)?shù)據(jù)可能在加利福尼亞,而另一部分可能在紐約,并且您可能會安排一個工作者角色在德克薩斯州對該數(shù)據(jù)進(jìn)行處理,而另一工作者角色在北達(dá)科他州進(jìn)行數(shù)據(jù)處理。很多開發(fā)人員在適應(yīng)這種分布式計算和分布式數(shù)據(jù)時面臨著一些不熟悉的問題,例如對可能出現(xiàn)的故障進(jìn)行編碼、針對數(shù)據(jù)提交形成多次重試的概念甚至冪等性的理念。只要您不將WindowsAzureQueue視為進(jìn)程內(nèi)的常規(guī)CLR隊(duì)列,其工作方式其實(shí)非常簡單。首先,應(yīng)用程序?qū)⑾蜿?duì)列獲取一些數(shù)量的消息(需要記住,一次不會超過20條)并提供一個超時。此超時控制對其他隊(duì)列處理客戶端隱藏這些消息的時間。當(dāng)應(yīng)用程序成功完成需要對隊(duì)列消息進(jìn)行的所有處理后,將刪除該消息。如果應(yīng)用程序引發(fā)異?;蛱幚黻?duì)列消息失敗,則在超時期限過后,其他客戶端可以再次看到該消息。因此,當(dāng)一個工作者角色處理失敗后,其他工作者角色可以繼續(xù)進(jìn)行處理。向隊(duì)列提交消息非常簡單:應(yīng)用程序直接或借助客戶端庫形成適當(dāng)?shù)腍TTPPOST消息,然后提交字符串或字節(jié)數(shù)組。隊(duì)列專門用于進(jìn)行內(nèi)部應(yīng)用程序消息傳送和非永久存儲,因此這些消息占用的空間需要相當(dāng)小。如上所述,您可能安排多個工作者角色都嘗試處理同一消息。雖然隱藏當(dāng)前正在處理的消息的不可見超時很有幫助,但不能確保萬無一失。要完全避免沖突,您應(yīng)該將您的引擎處理設(shè)計為冪等。換句話說,同一隊(duì)列消息應(yīng)該可以由一個或多個工作者角色處理多次,而不會使應(yīng)用程序處于不一致的狀態(tài)。理想情況下,您希望工作者角色可以檢測出是否已完成對給定消息的處理。在編寫工作者角色來處理隊(duì)列消息時,請牢記您的代碼可能會嘗試處理已處理過的消息,盡管這個可能性微乎其微。圖1中的代碼段顯示了如何使用隨WindowsAzureSDK一起提供的StorageClient程序集創(chuàng)建消息并將其提交給WindowsAzureQueue。StorageClient庫實(shí)際上只是WindowsAzureStorageHTTP接口周圍的包裝。圖1創(chuàng)建消息并將其提交給WindowsAzureQueuestringaccountName;
stringaccountSharedKey;
stringqueueBaseUri;
stringStorageCredentialsAccountAndKeycredentials;
if(RoleEnvironment.IsAvailable)
{
//Wearerunninginacloud-INCLUDINGLOCAL!
accountName=
RoleEnvironment.GetConfigurationSettingValue("AccountName");
accountSharedKey=
RoleEnvironment.GetConfigurationSettingValue("AccountSharedKey");
queueBaseUri=RoleEnvironment.GetConfigurationSettingValue
("QueueStorageEndpoint");
}
else
{
accountName=ConfigurationManager.AppSettings["AccountName"];
accountSharedKey=
ConfigurationManager.AppSettings["AccountSharedKey"];
queueBaseUri=
ConfigurationManager.AppSettings["QueueStorageEndpoint"];
}
credentials=
newStorageCredentialsAccountAndKey(accountName,accountSharedKey);
CloudQueueClientclient=
newCloudQueueClient(queueBaseUri,credentials);
CloudQueuequeue=client.GetQueueReference(queueName);
CloudQueueMessagem=newCloudQueueMessage(
/*stringorbyte[]representingmessagetoenqueue*/);
Queue.AddMessage(m);對于本文中的其他示例,我們使用了可以簡化此過程的一些包裝類(位于HollywoodHackers的CodePlex站點(diǎn)中,網(wǎng)址為:hollywoodhackers.codeplex/SourceControl/ListDownloadableCommits.aspx)。異步消息傳送(Toast)當(dāng)今,交互式網(wǎng)站不僅是一種時尚,更是一種需求。用戶已經(jīng)習(xí)慣了完全交互式網(wǎng)站,以致于當(dāng)他們遇到一個靜態(tài)的非交互式頁面時會認(rèn)為什么地方出問題了??紤]到這一點(diǎn),我們希望可以在我們的用戶使用這樣的站點(diǎn)時向他們發(fā)送通知。為此,我們將利用WindowsAzureQueue和WindowsAzureTable存儲機(jī)制構(gòu)建一個消息傳遞框架??蛻舳藢⑹褂门cjQueryGritter插件結(jié)合的jQuery在用戶的瀏覽器中將通知顯示為一個toast,類似于當(dāng)您收到新的Outlook電子郵件、即時消息或警報聲時在Windows系統(tǒng)托盤上方淡出的消息。當(dāng)需要向某個用戶發(fā)送通知時,該用戶將被插入到隊(duì)列中。因?yàn)楣ぷ髡呓巧?fù)責(zé)處理隊(duì)列中的每個項(xiàng)目,所以該角色將動態(tài)確定如何處理每個項(xiàng)目。在本例中,引擎只需要執(zhí)行一個操作,但在復(fù)雜的CRM網(wǎng)站或支持站點(diǎn)中,要執(zhí)行的操作可能不計其數(shù)。工作者角色在隊(duì)列中遇到用戶通知時,會將該通知存儲在表存儲中并將其從隊(duì)列中刪除。這樣,消息可以保留很長時間并等待用戶登錄進(jìn)行處理。隊(duì)列存儲中的消息的最大保存期限比較短,不會超過幾天。當(dāng)用戶訪問網(wǎng)站時,我們的jQuery腳本將異步獲取表中的所有消息,并通過在控制器上調(diào)用可返回JavaScriptObjectNotation(JSON)的方法在瀏覽器中以常見的形式顯示這些消息。盡管隊(duì)列只處理字符串或字節(jié)數(shù)組,但我們可以通過將任何類型的結(jié)構(gòu)化數(shù)據(jù)序列化為二進(jìn)制文件來將其存儲在隊(duì)列中,然后在我們需要使用時再將其轉(zhuǎn)換回來。這成為將強(qiáng)類型化的對象傳遞到隊(duì)列中的出色技術(shù)。我們會將此技術(shù)構(gòu)建到我們的隊(duì)列消息的基類中。然后,我們的系統(tǒng)消息類可以包含我們的數(shù)據(jù),而且可以將整個對象提交到隊(duì)列中并根據(jù)需要進(jìn)行利用(請參見圖2)。圖2在隊(duì)列中存儲結(jié)構(gòu)化數(shù)據(jù)namespaceHollywoodHackers.Storage.Queue
{
[Serializable]
publicclassQueueMessageBase
{
publicbyte[]ToBinary()
{
BinaryFormatterbf=newBinaryFormatter();
MemoryStreamms=newMemoryStream();
ms.Position=0;
bf.Serialize(ms,this);
byte[]output=ms.GetBuffer();
ms.Close();
returnoutput;
}
publicstaticTFromMessage(CloudQueueMessagem)
{
byte[]buffer=m.AsBytes();
MemoryStreamms=newMemoryStream(buffer);
ms.Position=0;
BinaryFormatterbf=newBinaryFormatter();
return(T)bf.Deserialize(ms);
}
}
[Serializable]
publicclassToastQueueMessage:QueueMessageBase
{
publicToastQueueMessage()
:base()
{
}
publicstringTargetUserName{get;set;}
publicstringMessageText{get;set;}
publicstringTitle{get;set;}
publicDateTimeCreatedOn{get;set;}
}請記住,要使用BinaryFormatter類,需要以完全信任模式(可以通過服務(wù)配置文件啟用此模式)運(yùn)行WindowsAzure工作者角色?,F(xiàn)在,我們需要一個簡單的包裝來與我們的隊(duì)列交互。從本質(zhì)上說,我們需要能夠?qū)⑾⒉迦腙?duì)列,獲取任何掛起的消息并清除該隊(duì)列(請參見圖3)。圖3用于與隊(duì)列交互的包裝namespaceHollywoodHackers.Storage.Queue
{
publicclassStdQueue:
StorageBasewhereT:QueueMessageBase,new()
{
protectedCloudQueuequeue;
protectedCloudQueueClientclient;
publicStdQueue(stringqueueName)
{
client=newCloudQueueClient
(StorageBase.QueueBaseUri,StorageBase.Credentials);
queue=client.GetQueueReference(queueName);
queue.CreateIfNotExist();
}
publicvoidAddMessage(Tmessage)
{
CloudQueueMessagemsg=
newCloudQueueMessage(message.ToBinary());
queue.AddMessage(msg);
}
publicvoidDeleteMessage(CloudQueueMessagemsg)
{
queue.DeleteMessage(msg);
}
publicCloudQueueMessageGetMessage()
{
returnqueue.GetMessage(TimeSpan.FromSeconds(60));
}
}
publicclassToastQueue:StdQueue
{
publicToastQueue()
:base("toasts")
{
}
}
}我們還需要為表存儲設(shè)置一個包裝,以便在用戶登錄到站點(diǎn)之前可以存儲用戶通知??梢允褂肞artitionKey(行集合的標(biāo)識符)和RowKey(可唯一標(biāo)識特定分區(qū)中的每個單獨(dú)行)組織表數(shù)據(jù)。選擇PartitionKey和RowKey使用的數(shù)據(jù)是在使用表存儲時所做的最重要的設(shè)計決策之一。這些特點(diǎn)允許跨存儲節(jié)點(diǎn)進(jìn)行負(fù)載平衡,并在應(yīng)用程序中提供內(nèi)置的可伸縮性選項(xiàng)。不考慮數(shù)據(jù)的數(shù)據(jù)中心關(guān)聯(lián)性,使用同一分區(qū)鍵的表存儲中的行將保留在相同的物理數(shù)據(jù)存儲中。因?yàn)獒槍γ總€用戶存儲對應(yīng)的消息,所以分區(qū)鍵將是UserName,而RowKey則成為標(biāo)識每行的GUID(請參見圖4)。圖4表存儲的包裝namespaceHollywoodHackers.Storage.Repositories
{
publicclassUserTextNotificationRepository:StorageBase
{
publicconststringEntitySetName=
"UserTextNotifications";
CloudTableClienttableClient;
UserTextNotificationContextnotificationContext;
publicUserTextNotificationRepository()
:base()
{
tableClient=newCloudTableClient
(StorageBase.TableBaseUri,StorageBase.Credentials);
notificationContext=newUserTextNotificationContext
(StorageBase.TableBaseUri,StorageBase.Credentials);
tableClient.CreateTableIfNotExist(EntitySetName);
}
publicUserTextNotification[]
GetNotificationsForUser(stringuserName)
{
varq=fromnotificationin
notificationContext.UserNotifications
wherenotification.TargetUserName==
userNameselectnotification;
returnq.ToArray();
}
publicvoidAddNotification
(UserTextNotificationnotification)
{
notification.RowKey=Guid.NewGuid().ToString();
notificationContext.AddObject
(EntitySetName,notification);
notificationContext.SaveChanges();
}
}
}因?yàn)槲覀兊拇鎯C(jī)制已經(jīng)確定,所以我們需要一個工作者角色作為引擎;以便在我們的電子商務(wù)站點(diǎn)的后臺處理消息。為此,我們定義了一個從Microsoft.ServiceHosting.ServiceRuntime.RoleEntryPoint類繼承的類,并將其與云服務(wù)項(xiàng)目中的工作者角色關(guān)聯(lián)(請參見圖5)。圖5作為引擎的工作者角色publicclassWorkerRole:RoleEntryPoint
{
ShoppingCartQueuecartQueue;
ToastQueuetoastQueue;
UserTextNotificationRepositorytoastRepository;
publicoverridevoidRun()
{
//Thisisasampleworkerimplementation.
//Replacewithyourlogic.
Trace.WriteLine("WorkerRole1entrypointcalled",
"Information");
toastRepository=newUserTextNotificationRepository();
InitQueue();
while(true)
{
Thread.Sleep(10000);
Trace.WriteLine("Working","Information");
ProcessNewTextNotifications();
ProcessShoppingCarts();
}
}
privatevoidInitQueue()
{
cartQueue=newShoppingCartQueue();
toastQueue=newToastQueue();
}
privatevoidProcessNewTextNotifications()
{
CloudQueueMessagecqm=toastQueue.GetMessage();
while(cqm!=null)
{
ToastQueueMessagemessage=
QueueMessageBase.FromMessage(cqm);
toastRepository.AddNotification(new
UserTextNotification()
{
MessageText=message.MessageText,
MessageDate=DateTime.Now,
TargetUserName=message.TargetUserName,
Title=message.Title
});
toastQueue.DeleteMessage(cqm);
cqm=toastQueue.GetMessage();
}
}
privatevoidProcessShoppingCarts()
{
//Wewilladdthislaterinthearticle!
}
publicoverrideboolOnStart()
{
//Setthemaximumnumberofconcurrentconnections
ServicePointManager.DefaultConnectionLimit=12;
DiagnosticMonitor.Start("DiagnosticsConnectionString");
//Frmationonhandlingconfigurationchanges
//seetheMSDNtopicat
//go.microsoft/fwlink/?LinkId=166357.
RoleEnvironment.Changing+=RoleEnvironmentChanging;
returnbase.OnStart();
}
privatevoidRoleEnvironmentChanging(objectsender,RoleEnvironmentChangingEventArgse)
{
//Ifaconfigurationsettingischanging
if(e.Changes.Any(change=>changeisRoleEnvironmentConfigurationSettingChange))
{
//Sete.Canceltotruetorestartthisroleinstance
e.Cancel=true;
}
}
}讓我們看一下工作者角色代碼。在初始化和設(shè)置所需的隊(duì)列和表存儲之后,此代碼將進(jìn)入一個循環(huán)。每10秒鐘,它就會處理一次隊(duì)列中的消息。每次我們通過處理循環(huán)時都將獲取隊(duì)列中的消息,直到最終返回null,這表示隊(duì)列為空。您從隊(duì)列中看到的消息永遠(yuǎn)不會超過20個,如果不信,您可以反復(fù)嘗試來驗(yàn)證一下。對隊(duì)列進(jìn)行的任何處理都有時間限制,必須在該時間范圍內(nèi)對每個隊(duì)列消息執(zhí)行有意義的操作,否則隊(duì)列消息將被視為超時,并在隊(duì)列中顯示備份,以便可以由其他工作者來處理此消息。每個消息都會作為用戶通知添加到表存儲中。關(guān)于工作者角色需要記住的重要一點(diǎn)是:一旦入口點(diǎn)方法完成,工作者角色也就結(jié)束了。這就是您需要在一個循環(huán)中保持邏輯運(yùn)行的原因。從客戶端的角度來說,我們需要能夠以JSON形式返回消息,以便jQuery可以異步輪詢并顯示新的用戶通知。為此,我們會將一些代碼添加到消息控制器中,以便可以訪問這些通知(請參見圖6)。圖6以JSON形式返回消息publicJsonResultGetMessages()
{
if(User.Identity.IsAuthenticated)
{
UserTextNotification[]userToasts=
toastRepository.GetNotifications(User.Identity.Name);
object[]data=
(fromUserTextNotificationtoastinuserToasts
selectnew{title=toast.Title??"Notification",
text=toast.MessageText}).ToArray();
returnJson(data,JsonRequestBehavior.AllowGet);
}
else
returnJson(null);
}在VisualStudio2010beta2下的ASP.NETMVC2(我們用于撰寫本文的環(huán)境)中,如果沒有JsonRequestBehavior.AllowGet選項(xiàng),您無法將JSON數(shù)據(jù)返回到j(luò)Query或其他客戶端。在ASP.NETMVC1中,不需要此選項(xiàng)?,F(xiàn)在,我們可以編寫JavaScript,它每15秒將調(diào)用一次GetMessages方法并將以toast形式消息顯示通知(請參見圖7)。圖7以toast形式消息顯示的通知$(document).ready(function(){
setInterval(function(){
$.ajax({
contentType:"application/json;charset=utf-8",
dataType:"json",
url:"/SystemMessage/GetMessages",
success:function(data){
for(msgindata){
$.gritter.add({
title:data[msg].title,
text:data[msg].text,
sticky:false
});
}
}
})
},15000)
});提交和處理購物車在我們的示例應(yīng)用程序中,我們希望使用隊(duì)列存儲執(zhí)行的另一個關(guān)鍵方案是提交購物車。HollywoodHackers有一個第三方履行系統(tǒng)(HollywoodHackers無法在其空間有限的倉庫中保留所有小工具),所以引擎需要對購物車進(jìn)行一些處理。一旦引擎完成其處理,它會向用戶通知隊(duì)列提交一個消息,告知用戶已經(jīng)對購物車進(jìn)行了處理(或者出現(xiàn)了問題)。如果處理購物車時用戶處于在線狀態(tài),該用戶將收到系統(tǒng)彈出的一個toast消息。如果用戶不在線,則會在其下次登錄到該站點(diǎn)時收到該彈出消息,如圖8所示。圖8示例用戶通知查看原圖(大圖)我們首先需要的是一些包裝類,使我們可以與購物車隊(duì)列交互。這些包裝非常簡單,如果要查看它們的源代碼,可以在CodePlex站點(diǎn)上查看。與標(biāo)準(zhǔn)CRUD(創(chuàng)建、讀取、更新、刪除)存儲庫不同的是,隊(duì)列中的讀取操作不是單純的讀取操作。請記住,只要獲取隊(duì)列中的消息,必須在有限的時間內(nèi)處理該消息,操作失敗或刪除消息都會顯示處理完成。這種模式不能順利地轉(zhuǎn)換到存儲庫模式,所以我們已經(jīng)不再借助包裝類執(zhí)行此操作?,F(xiàn)在,我們已經(jīng)擁有了要與購物車隊(duì)列交互的代碼,我們可以將一些代碼放在購物車控制器中,以便將購物車內(nèi)容提交到隊(duì)列中(請參見圖9)。圖9向隊(duì)列提交購物車publicActionResultSubmit()
{
ShoppingCartMessagecart=newShoppingCartMessage();
cart.UserName=User.Identity.Name;
cart.Discounts=12.50f;
cart.CartID=Guid.NewGuid().ToString();
Listitems=newList();
items.Add(newShoppingCartItem()
{Quantity=12,SKU="10000101010",
UnitPrice=15.75f});
items.Add(newShoppingCartItem()
{Quantity=27,SKU="12390123j213",
UnitPrice=99.92f});
cart.CartItem
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 45155-2024質(zhì)量管理理解、評價和改進(jìn)組織的質(zhì)量文化指南
- Perfluoropentane-Dodecafluoropentane-生命科學(xué)試劑-MCE-3888
- Ergocornine-生命科學(xué)試劑-MCE-6625
- 10-Norparvulenone-生命科學(xué)試劑-MCE-1894
- 二零二五年度智能制造股權(quán)融資協(xié)議
- 二零二五年度游戲軟件試用授權(quán)合同
- 二零二五年度企業(yè)退休人員再就業(yè)解除合同協(xié)議
- 2025年度貨運(yùn)駕駛員綠色出行與節(jié)能減排合同
- 2025年度新能源項(xiàng)目電力施工簡易協(xié)議書
- 2025年度豪華公寓私人房屋轉(zhuǎn)租管理服務(wù)合同
- 第十五章《探究電路》復(fù)習(xí)課課件滬科版九年級物理
- 2024年中考物理科技創(chuàng)新題型(教師版)
- 唐山市重點(diǎn)中學(xué)2024-2025學(xué)年全國高考大聯(lián)考信息卷:數(shù)學(xué)試題試卷(3)含解析
- 未成年上班知情協(xié)議書
- 2024年山東藥品食品職業(yè)學(xué)院單招職業(yè)適應(yīng)性測試題庫含答案
- 2023-2024學(xué)年高中政治統(tǒng)編版選擇性必修二7-1 立足職場有法寶 課件(34張)
- 2024年高考語文標(biāo)點(diǎn)符號的基本用法大全(新標(biāo)準(zhǔn))
- 恩施州巴東縣核桃樹煤礦有限公司核桃樹煤礦礦產(chǎn)資源開發(fā)利用與生態(tài)復(fù)綠方案
- 部編版語文一年級下冊全冊大單元整體作業(yè)設(shè)計
- 學(xué)生平板電腦使用規(guī)則
- 電子技術(shù)的發(fā)展和應(yīng)用
評論
0/150
提交評論