Silverlight 2.0 資料庫應用程式開發(1)

 

Silverlight 2.0 資料庫應用程式開發 (1)
 
 
/ 黃忠成
 
Silverlight 1.0 Silverlight 2.0
 
   我想不用我贅言,相較於 Silverlight 1.0 的陽春, Silverlight 2.0 提供了更完整的資料庫支援,其最主要的部份在於提供了 WCF/HTTP 的網路機制及客戶端的控件 Binding 技術,有了這兩個機制,我們可以透過 WCF/HTTP 網路機制連回 Server 端取得資料,然後以 Binding 技術將控件與資料結合在一起,設計出類似 Windows Form/WPF UI 介面的強大網頁資料庫應用程式。
 
Silverlight 2.0 N-Tier
 
   對於部份的 ASP.NET 設計師而言,對 Silverlight 2.0 的資料庫應用程式的開發模式會有些陌生,在 ASP.NET 設計模式中,我們可以直接使用 ADO.NET 來取得資料,接著利用 GridView 等資料控件將資料顯現於網頁上,此時的系統架構如圖 SL001
SL001
但在 Silverlight 2.0 中,並未提供 ADO.NET 這個機制,從網頁應用程式角度上看, Silverlight 2.0 是一種 Client Application 架構,運行於 IE 等瀏覽器平台之上,因此若要提供 ADO.NET 機制,那麼後端的資料庫必定得曝露於網際網路之上,而你肯定無法接受將 SQL Server 曝露在網路上供人存取,因為這會帶來安全性、授權費等問題。所以,當使用 Silverlight 2.0 時,我們必須找一個相對於 ADO.NET 的機制來做為取得資料的中介層,這種設計模式就稱為 N-Tier ,見圖 SL002
SL002
如圖 SL002 所示, Silverlight 應用程式是內嵌於 HTML 中下載,她可以透過 WCF/HttpWebRequest 網路機制連回來源的 Web Site 取得資料,問題在於後端的 Web Site 如何接收來自 Silverlight 的網路要求?在 Silverlight 2.0 中,你有兩種選擇,一是在 Web Site 端建立一個簡單的網頁,收取來自 Silverlight 的網路要求,接著輸出 XML 或是 JSON 格式的資料。二是透過 .NET WCF 機制,於 Web Site 端建立一個 WCF Service ,於 Silverlight 中透過此 WCF Service 來取得資料。兩種機制各有其優缺點,方法一可以適用於所有網頁平台,例如 ASP PHP JSP 皆可,而方法二則是僅限於支援 Web Service 的網頁平台。
 
  在開始設計實際應用程式之時,你必須先了解所謂 N-Tier 架構的定義,所謂的 N-Tier 指的是將整個程式架構切分為三個層面,第一層是展現層,也就是你的 Silverlight 應用程式,用來顯示資料及接受使用者操作,第二層指的服務層,用來提供資料及回應來自展示層的要求,第三層則是資料層,用來由資料庫取得資料或是更新資料。 N-Tier 早期的發展是為了分擔資料庫系統的繁重工作,以 [ 偶而連線 ] [ 負載平衡 ] 等技巧,減輕本來必須全部交與資料庫處理的工作。舉個例來說,一系統擁有 10000 個使用者,當使用傳統的 Client/Server 架構時,這 10000 個使用者會握有 10000 個資料連線,當這些使用者發出要求資料的 SELECT 需求時,資料庫系統就得負擔產生 10000 個資料集的工作,但這 10000 個需求中,很有可能有一半以上是要求同一份資料。當使用 N-Tier 架構時,我們就可以在服務層中快取已取過的資料,當有同樣要求來臨時,直接以回傳快取資料的方式取代由資料庫系統取得的動作,這樣自然就減輕了資料庫的負擔,提高系統所能承載的用戶數量。
 
  在早期網際網路頻寬不足的環境下, N-Tier 架構原始設計中每個動作都要透過連結服務層的模式顯得有些不切實際,因為使用者可能處於一個低頻寬的環境、甚至是無網路可用的窘境,在這種模式下,存取服務層是種奢侈。因此, N-Tier 發展出一種名為 [ 偶爾連線 ] 的模式,展示層在有網路的情況下,將資料由服務層取回後快取於客戶端,此時使用者可以自由的操作展示層來新增、修改、刪除及查詢資料,這些動作全以客戶端的快取為主,待有網路時,再將異動資料整批傳回服務層更新回資料庫。
 
 [ 偶爾連線 ] 的架構很完美,也很符合當年的需求,但隨著網路的普遍化及高覆蓋率,設計 [ 偶而連線 ] 架構所需付出的代價就顯得有些累贅了, [ 偶爾連線 ] 的架構建立在完善的客戶端快取機制及客戶端查詢機制下,而這些機制並不容易建構。所以,現在的 N-Tier 轉變為以 [ 連線模式 ] 為主。
 
 Silverlight 2.0 的架構趨近於 [ 連線模式 ] ,這意味著 Silverlight 2.0 的應用程式將運行在一個可存取網站的環境下,當這個網站存在於本機時,程式不需要網路便可執行,當網站不存在於本機時,則需要網路方能運行。

註:多數瀏覽器都有一種以離線模式執行網頁的設定,將離線模式打開,你依舊能在離線模式下運行 Silverlight 程式,在適當的設計下,其實也能做出 [ 偶爾連線 ] 模式。

 
 
使用 HttpWebRequest
 
  在大略了解 Silverlight 2.0 N-Tier 架構後,我們便可以開始撰寫 Silverlight 2.0 的資料庫應用程式,請建立一個 Silverlight 2.0 專案,接著於 Web 結尾之 Project 添加一資料庫。
SL003
SL004
然後添加一資料表至資料庫中。
SL005
建立結構。
SL006
添加資料列。
SL007
SL008
完成資料庫準備工作後,現在便可開始實作服務層,在這小節中,我們以傳統網頁模式來建立服務層,請於 Web 結尾之專案中添加一 Generic Handler( 你也可以使用 .aspx)
SL009

DBProvider.ashx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Xml.Linq;
 
namespace DBDemo1.Web
{
    ///<summary>
    /// Summary description for $codebehindclassname$
    ///</summary>
    public class DBProvider : IHttpHandler
    {
 
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/xml";
            using (SqlConnection conn = new SqlConnection(@"Data Source=./SQLEXPRESS;AttachDbFilename=|DataDirectory|/MyDatabase.mdf;Integrated Security=True;User Instance=True"))
            {
                XDocument doc = new XDocument(new XElement("Root"));
                using (SqlCommand cmd = new SqlCommand("SELECT * FROM CUSTOMERS", conn))
                {
                    conn.Open();
                    using (SqlDataReader reader = cmd.ExecuteReader(
                                         CommandBehavior.CloseConnection))
                    {
                        while (reader.Read())
                        {
                            XElement elem = new XElement("Customer");
                            elem.Add(new XAttribute("CUSTOMER_ID",
                               reader.GetString(reader.GetOrdinal("CUSTOMER_ID"))));
                            elem.Add(new XAttribute("CUSTOMER_NAME",
                               reader.GetString(reader.GetOrdinal("CUSTOMER_NAME"))));
                            doc.Root.Add(elem);
                        }
                    }
                    context.Response.Write(doc.ToString());
                    context.Response.Flush();
                    context.Response.End();
                }
            }
        }
 
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

透過 IE 來測試此服務層是否運作正常。
SL010
由於本例將使用 DataGrid 控件,因此你必須透過 Add Reference( 加入參考 ) 來添加 DataGrid 所需要的 Assembly Silverlight 專案 ( 沒有 Web 結尾的那一個 )
SL011
SL012
另外,由於服務層使用 XML ,我們可以利用 Silverlight 2.0 所提供的 LINQ To XML 來簡化解譯 XML 的工作, LINQ To XML 需要添加 System.XML.Linq.dll 為參考,請透過 Add Reference 來添加 System.XML.Linq.dll Silverlight 專案中 ( 沒有 Web 結尾的那一個 )
SL013
接著在 Page.xaml 中鍵入以下的 XAML

Page.xaml
< UserControl x : Class ="DBDemo1.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
    Width="400" Height="300" Loaded="UserControl_Loaded">
    < Grid x : Name ="LayoutRoot" Background ="White" Height ="300" Width ="400">
        < data : DataGrid x : Name ="grid" AutoGenerateColumns ="True">
        </ data : DataGrid >
    </ Grid >
</ UserControl >

最後在 Page.xaml.cs 中鍵入以下的程式碼。

Page.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Xml;
using System.Xml.Linq;
 
namespace DBDemo1
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
        }
 
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
                new Uri("http://localhost:40419/DBProvider.ashx", UriKind.Absolute));
            request.Method = "POST";
            request.BeginGetRequestStream(new AsyncCallback(ReadCallback),request);
        }
 
        private void ReadCallback(IAsyncResult state)
        {
            HttpWebRequest request = (HttpWebRequest)state.AsyncState;           
            Stream postStream = request.EndGetRequestStream(state);
            //byte[] buff = System.Text.Encoding.Unicode.GetBytes("TEST");
            //postStream.Write(buff, 0, buff.Length);
            postStream.Close(); // the request stream must closed before
            request.BeginGetResponse(new AsyncCallback(GetResponse), request);
        }
 
        private void GetResponse(IAsyncResult state)
        {
            HttpWebRequest request = (HttpWebRequest)state.AsyncState;
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(state);
            using (Stream stream = response.GetResponseStream())
            {
                XDocument doc = XDocument.Load(stream);
                Dispatcher.BeginInvoke(
                  new System.Threading.ParameterizedThreadStart(UpdateUI), doc);
            }
        }
 
       private void UpdateUI(object state)
        {
            XDocument doc = (XDocument)state;
            grid.ItemsSource = (from s1 in doc.Elements("Root").Descendants("Customer")
                                select new Customer()
                                    {
                                       ID = s1.Attribute("CUSTOMER_ID").Value,
                                       Name = s1.Attribute("CUSTOMER_NAME").Value
                                    }).ToList();
        }
    }
 
    public class Customer
    {
        public string ID { get; set; }
        public string Name { get; set; }
    }
}

SL014 是此例執行結果。
SL014
透過 HttpWebRequest 的模式,我們可以用傳統網頁來扮演服務層,這可應用於多數網頁平台如 PHP ASP JSP 之上。
 
使用 WCF
 
   使用 HTTPWebRequest 的方式雖然簡單,但缺點是我們得自訂其間資料傳送的格式,最大化相容性的結果也限縮了結構性,所幸在現今網路世界中早已定義了多數網頁平台都支援的資料格式,那就是 SOAP/Web Service Silverlight 2.0 除了允許我們撰寫 Web Service 的客戶端外,同時也支援了 .NET Framework 3.0 中所新增的 WCF Service ,本例就以 WCF Service 做為服務層,請添加一個 Web Service Web 結尾的專案中。
SL015
然後添加一個 LINQ To SQL Classes Web 結尾的專案中,做為取代 ADO.NET 的資料存取機制。
SL016
添加資料表至 .DBML 中。
SL017
刪除自動產生的 IDBService.cs ,然後於 DBService.svc.cs 中鍵入以下程式碼。

DBService.svc.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
 
namespace DBDemo1.Web
{
    [ServiceContract]
    public interface IDBService
    {
        [OperationContract]
        CUSTOMERS[] GetData();
    }
   
    public class DBService : IDBService
    {       
        public CUSTOMERS[] GetData()
        {
            using (MyDBDataContext context = new MyDBDataContext())
            {
                return (from s1 in context.CUSTOMERS select s1).ToArray();
            }
        }
    }
}

修改 web.config serviceModel 區段的設定。

web.config
............
< services >
   < service behaviorConfiguration = "DBDemo1.Web.DBServiceBehavior"
               name = "DBDemo1.Web.DBService">
    < endpoint address = ""binding="basicHttpBinding"contract="DBDemo1.Web.IDBService">
     < identity >
      < dns value = "localhost" />
     </ identity >
    </ endpoint >
    < endpoint address = "mex"binding="mexHttpBinding"contract="IMetadataExchange" />
   </ service >
 </ services >
............

Silverlight 專案中,添加一 Service Reference( 服務參考 )
SL018
SL019
添加一 Silverlight UserControl
SL020
程式碼如下所示。

Page2.xaml
< UserControl x : Class ="DBDemo1.Page2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
    Width="400" Height="300" Loaded="UserControl_Loaded">
    < Grid x : Name ="LayoutRoot" Background ="White" Height ="300" Width ="400">
        < data : DataGrid x : Name ="grid" AutoGenerateColumns ="True">
        </ data : DataGrid >
    </ Grid >
</ UserControl >
Page2.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
 
namespace DBDemo1
{
    public partial class Page2 : UserControl
    {
        public Page2()
        {
            InitializeComponent();
        }
 
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {           
            ServiceReference1.DBServiceClient client =
                 new DBDemo1.ServiceReference1.DBServiceClient();
            client.GetDataCompleted +=
             new EventHandler<DBDemo1.ServiceReference1.GetDataCompletedEventArgs>(
               client_GetDataCompleted);
            client.GetDataAsync();
        }
 
        void client_GetDataCompleted(object sender,
                     DBDemo1.ServiceReference1.GetDataCompletedEventArgs e)
        {
            grid.ItemsSource = e.Result;
        }
    }
}

此例執行結果同前例。
 
使用 ADO.NET Data Service Framework
 
   WCF/Web Service 做為服務層雖然很完美,但設計師仍然得自行定義取得資料、查詢資料、更新資料的函式,在 .NET Framework 3.5 中,這些工作可以交給 ADO.NET Data Service Framework 來負責,這樣可以減輕設計師自行架構服務層規格的負擔,也能統一個別服務層的規格,避免不同設計師設計出不同的規格。預設情況下, ADO.NET Data Service Framework 的資料層必須是 ADO.NET Entity Framework ,所以請於 Web 結尾的專案中添加一 ADO.NET Entity Data Model 項目。
SL021
SL022
SL023
 
SL024
完成後,在 Web 結尾的專案中添加一個 ADO.NET Data Service 項目。
SL025
WebDataService1.svc.cs 中鍵入以下程式碼。

WebDataService1.svc.cs
using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;
 
namespace DBDemo1.Web
{
    public class WebDataService1 : DataService< EntityData.MyDatabaseEntities>
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(IDataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
            config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
        }
    }
}

完成後編譯專案,接著於 Silverlight 2.0 添加一 Service Reference
SL026
然後於 Silverlight 專案中添加一新的 Silverlight User Control

Page3.xaml
< UserControl x : Class ="DBDemo1.Page3"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
    Width="400" Height="300" Loaded="UserControl_Loaded">
    < Grid x : Name ="LayoutRoot" Background ="White" Height ="300" Width ="400">
        < data : DataGrid x : Name ="grid" AutoGenerateColumns ="True">
        </ data : DataGrid >
    </ Grid >
</ UserControl >
Page3.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Data.Services.Client;
 
namespace DBDemo1
{
    public partial class Page3 : UserControl
    {
        public Page3()
        {
            InitializeComponent();
        }
 
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            ServiceReference2.MyDatabaseEntities3 entities =
            new DBDemo1.ServiceReference2.MyDatabaseEntities3(
               new Uri("WebDataService1.svc",UriKind.Relative));
            var result = from s1 in entities.CUSTOMERS select s1;
            ((DataServiceQuery<ServiceReference2.CUSTOMERS>)result).BeginExecute(
                      new AsyncCallback(ReadCallback), result);
        }
 
        private void ReadCallback(IAsyncResult state)
        {
            DataServiceQuery<ServiceReference2.CUSTOMERS> svcCtx =
                (DataServiceQuery<ServiceReference2.CUSTOMERS>)state.AsyncState;
            //remember, you must call tolist,toarray before set to itemsource.
            grid.ItemsSource = svcCtx.EndExecute(state).ToList();
        }
    }
}

此例執行結果如前例。使用 ADO.NET Data Service 的好處在於能統一存取資料時的服務端規格,尤其在 Silverlight 2.0 所提供的 ADO.NET Data Service Client Framework 的幫助下,設計師還能輕鬆的更新資料庫,其間資料傳遞及異動機制都不需要設計師操心。
 
實作 [ 偶而連線 ] 模式
 
   或許你曾經聽過, Sivlerlight 不支援離線操作這檔事,事實的確是如此,但這指的是 Silverlight 不能像 Flash 般,包成一單一的執行檔來執行,透過 IE 等瀏覽器提供的離線模式,在沒有網路的情況下運行 Silverlight 程式依舊是可行的,前提是你的程式必須運用 Silverlight 2.0 中的 Isolate Storage 機制來儲存快取資料,而使用者至少需連線一次,讓相關的 Silverlight 程式下載到客戶端,下面的程式是一個可離線操作的簡單例子。

Page4.xaml
< UserControl x : Class ="DBDemo1.Page4"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
    Width="400" Height="300" Loaded="UserControl_Loaded">
    < Grid x : Name ="LayoutRoot" Background ="White" Height ="300" Width ="400">
        < data : DataGrid x : Name ="grid" AutoGenerateColumns ="True">
        </ data : DataGrid >
    </ Grid >
</ UserControl >
Page4.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.IO.IsolatedStorage;
using System.Xml.Linq;
 
 
namespace DBDemo1
{
    public partial class Page4 : UserControl
    {
        public Page4()
        {
            InitializeComponent();
        }
 
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
                 new Uri("http://localhost:40419/DBProvider.ashx", UriKind.Absolute));
            request.Method = "POST";
            request.BeginGetRequestStream(new AsyncCallback(ReadCallback), request);
        }
 
        private void ReadCallback(IAsyncResult state)
        {
            HttpWebRequest request = (HttpWebRequest)state.AsyncState;
            Stream postStream = request.EndGetRequestStream(state);
            //byte[] buff = System.Text.Encoding.Unicode.GetBytes("TEST");
            //postStream.Write(buff, 0, buff.Length);
            postStream.Close(); // the request stream must closed before
            request.BeginGetResponse(new AsyncCallback(GetResponse), request);
        }
 
        private void GetResponse(IAsyncResult state)
        {
            try
            {
                HttpWebRequest request = (HttpWebRequest)state.AsyncState;
                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(state);
                using (Stream stream = response.GetResponseStream())
                {
                    using (var store = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        store.CreateDirectory("Data");
                        IsolatedStorageFileStream subDirFile =
                          store.CreateFile(System.IO.Path.Combine("Data", "dbdata.txt"));
                        using (StreamWriter sw = new StreamWriter(subDirFile))
                        {
                            using(StreamReader sr = new StreamReader(stream))
                            {
                                sw.Write(sr.ReadToEnd());
                            }
                        }
 
                    }
                    XDocument doc = XDocument.Load(stream);
                    Dispatcher.BeginInvoke(
                       new System.Threading.ParameterizedThreadStart(UpdateUI), doc);
                }
            }
            catch (Exception ex)
            {
                using (var store = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    IsolatedStorageFileStream subDirFile =
                store.OpenFile(System.IO.Path.Combine("Data", "dbdata.txt"),FileMode.Open);
                    XDocument doc = XDocument.Load(subDirFile);
                    subDirFile.Close();
                    Dispatcher.BeginInvoke(
                  new System.Threading.ParameterizedThreadStart(UpdateUI), doc);
                }
            }
        }
 
        private void UpdateUI(object state)
        {
            XDocument doc = (XDocument)state;
            grid.ItemsSource = (from s1 in doc.Elements("Root").Descendants("Customer")
                                select new Customer()
                                {
                                    ID = s1.Attribute("CUSTOMER_ID").Value,
                                    Name = s1.Attribute("CUSTOMER_NAME").Value
                                }).ToList();
        }
    }
}

適當使用 Isolate Storage 來儲存資料快取,可以讓應用程式減少網路流量,達到提升效率的目的。
SL027
 
Next Time...
 
  下次有機會的話,我們再來討論較進階的資料庫應用程式撰寫技巧,例如異動資料、查詢及處理關聯等等。
 
内容概要:本文提出了一种基于非合作博弈理论的居民负荷分层调度模型,并结合双层鲸鱼优化算法(Two-level Whale Optimization Algorithm)进行高效求解,模型与算法均通过Matlab代码实现。研究针对电力系统中居民侧用电负荷的复杂调度问题,引入非合作博弈机制刻画各用户之间的利益竞争关系,实现负荷的分层优化分配;同时设计双层优化架构,上层优化资源配置,下层模拟用户自主决策行为,提升了模型的实用性与合理性。通过智能优化算法求解多层级、非凸非线性的博弈模型,有效提高了调度方案的收敛性与全局寻优能力,适用于现代智能电网中的需求侧管理与能源优化场景。; 适合人群:具备电力系统基础理论知识和Matlab编程能力,从事智能电网、能源优化调度、需求侧管理、博弈论应用等方向的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①应用于居民区电力负荷的分层优化调度系统设计与仿真分析;②为非合作博弈在多主体能源系统建模中的应用提供方法论支持;③利用双层鲸鱼算法解决具有嵌套结构的复杂双层优化问题,提升求解效率与调度方案的可行性。; 阅读建议:建议读者结合提供的Matlab代码深入理解模型构建逻辑与算法实现流程,重点关注博弈模型的效用函数设计、纳什均衡求解思路以及双层优化结构的迭代机制,宜配合实际用电数据开展复现实验以验证模型有效性与鲁棒性。
内容概要:本文围绕基于自适应神经模糊推理系统(ANFIS)智能控制器的可再生能源微电网功率管理系统展开研究,结合Simulink仿真实现,深入探讨了微电网中功率的智能调控与经济机组组合调度问题。通过引入ANFIS控制器,有效应对风能、光伏等可再生能源出力的波动性与不确定性,提升系统运行的稳定性与电能质量。研究内容涵盖微电网多源协调控制策略、功率平衡管理、优化调度模型构建及仿真验证,实现了对分布式电源、储能系统和负荷的协同优化,兼顾经济性与可靠性目标,并通过仿真平台验证了所提方法的有效性与优越性。; 适合人群:具备电力系统、自动化或新能源相关专业背景,熟悉Matlab/Simulink仿真环境,从事微电网能量管理、智能控制、能源优化等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于高比例可再生能源接入场景下的微电网能量管理系统研发与教学实践;②为实现微电网功率稳定控制与经济高效运行提供先进的智能控制解决方案;③支撑高水平学术论文复现、科研课题攻关及实际工程项目的仿真验证与方案优化。; 阅读建议:建议结合提供的Simulink模型与相关代码进行动手实践,重点关注ANFIS控制器的设计流程、规则库构建与参数调优方法,并通过与传统PID或MPC控制策略的对比实验,深入理解其在动态响应与鲁棒性方面的优势。同时可进一步拓展文中提出的优化调度逻辑,应用于多目标、多约束的复杂实际应用场景中。
内容概要:本文档聚焦于“直流电机双闭环控制Matlab仿真”,系统阐述了基于Matlab/Simulink平台实现直流电机双闭环控制系统(主要包括速度环与电流环)的设计与仿真全过程。通过构建直流电机的数学模型,结合PI控制器进行调控,实现对电机转速和电枢电流的高精度动态控制,验证控制策略的稳定性与响应性能。文档详细介绍了仿真模型的搭建流程、关键参数的整定方法、系统动态波形的分析手段以及仿真结果的有效性验证,体现了经典自动控制理论在实际电机系统中的工程应用,是电机控制与电力电子技术相结合的典型研究案例。; 适合人群:具备自动控制原理、电机与拖动基础、电力电子技术和Matlab/Simulink仿真能力的电气工程、自动化、机电一体化等专业的本科生、研究生及从事电机驱动系统研发的工程技术人员。; 使用场景及目标:①作为高校课程设计或实验教学材料,帮助学生深入理解双闭环调速系统的工作机理与工程实现;②服务于科研项目,为新型电机控制算法(如滑模、模糊PID等)的开发与性能对比提供基础仿真验证平台;③作为工业界产品前期设计的仿真工具,用于评估不同控制策略在动态响应、抗干扰能力和稳态精度方面的可行性。; 阅读建议:建议读者在学习过程中紧密结合自动控制理论知识,亲手在Simulink环境中搭建完整的双闭环仿真模型,通过反复调整PI控制器的比例与积分参数,观察并分析转速、电流的阶跃响应曲线,从而深刻理解反馈控制的本质、系统稳定性条件以及参数整定对动态性能的影响,进而掌握电机控制系统的设计精髓。
内容概要:本文研究了基于Benders分解与输电网运营商(TSO)和配电网运营商(DSO)协调机制的不确定环境下输配电网双层优化模型,旨在提升高比例可再生能源接入背景下电网系统的协调性与鲁棒性。模型上层以系统整体经济性为目标进行优化调度,下层采用Benders分解实现TSO与DSO之间的信息交互与协同决策,通过引入割平面迭代机制保障求解的收敛性与全局最优性。研究充分考虑新能源出力与负荷需求的不确定性,构建了具有强适应性的双层优化框架,并基于Matlab完成了模型的编程实现与仿真验证,有效解决了多主体、多层级、多不确定性因素耦合下的电力系统优化调度难题。; 适合人群:具备电力系统分析、运筹学与优化理论基础,熟悉Matlab编程环境,从事智能电网、能源互联网、分布式能源集成、电力市场等方向的研究生、科研人员及工程技术人员。; 使用场景及目标:①研究高渗透率可再生能源条件下输配电网协同优化调度策略;②掌握Benders分解在电力系统双层优化建模中的应用方法与实现技巧;③构建TSO-DSO多主体协调机制,实现跨层级电网资源的高效互动与决策解耦;④提升对不确定性建模、分解算法设计及大规模优化问题求解能力。; 阅读建议:建议读者结合Matlab代码逐模块剖析模型构建流程,重点理解Benders割的生成逻辑、主从问题的信息传递机制及收敛判据设定,推荐在标准IEEE测试系统上复现实验以深入掌握模型特性与算法性能。
内容概要:本文系统研究了基于灰狼优化算法(GWO)优化Elman神经网络的方法,并提供了完整的Matlab代码实现。研究重点在于利用灰狼优化算法强大的全局搜索能力,对Elman神经网络的关键参数进行智能优化,从而克服传统训练方法易陷入局部最优的缺陷,显著提升模型在时序预测与非线性系统建模任务中的精度与稳定性。文章详细阐述了Elman网络的动态反馈机制及其在处理时间序列数据方面的优势,构建了GWO与Elman相结合的混合预测框架,涵盖了从模型搭建、参数寻优、仿真测试到结果分析的全流程,特别适用于风电功率预测、电力负荷预测等具有强时变性和不确定性的工程应用场景。; 适合人群:具备一定Matlab编程能力和神经网络基础知识,从事智能优化算法、时间序列预测、电力系统分析或新能源出力预测等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握灰狼优化算法在神经网络超参数优化中的具体实施路径与技术细节;②深入理解Elman递归神经网络与群体智能优化算法融合的建模范式;③将其应用于风电、光伏等新能源发电功率预测及复杂动态系统的建模与仿真,提升预测性能。; 阅读建议:建议读者结合所提供的Matlab代码进行动手实践,重点关注GWO算法与Elman网络的接口设计、适应度函数构建及参数优化迭代过程,可通过调整数据集或迁移至其他预测场景以深化理解和验证模型泛化能力。
源码直接下载地址: https://pan.quark.cn/s/a4b39357ea24 JMeter的录制方法及过滤策略、线程组构成要素是什么? JMeter能够借助第三方录制工具(如BadBoy)或其自带的录制功能来完成录制工作,JMeter的录制机制:是借助HTTP代理服务器来捕获用户在操作网站时产生的链接信息。JMeter允许在配置HTTP代理服务器时,排除掉非必要的CSS、GIF等资源,以此减轻不必要的负担。 线程组涵盖:线程组的名称标识、附加注释说明、线程组内的用户数量、线程组完成请求的时间分配、循环执行次数、时间调度机制 【JMeter性能测试详解】 JMeter是一款功能强大的性能测试软件,常用于模拟大规模用户同时访问Web应用,用以衡量系统的性能表现和稳定性。接下来将具体说明JMeter的操作方法、线程组的设置以及性能测试的重要环节。 **JMeter录制与过滤** JMeter可以通过BadBoy等外部工具或其自带的HTTP代理服务器来记录用户的行为。其录制原理是JMeter作为HTTP代理,拦截用户浏览器发出的所有网络请求。在配置代理服务器时,能够过滤掉不必要的CSS、GIF等静态资源,以减少无效的负载。 **线程组配置** 线程组是JMeter测试计划的核心部分,包含以下几个关键参数: 1. **线程组名**:用于区分测试计划中的不同测试区域。 2. **注释**:用于记录测试目标或注意事项。 3. **线程数**:用于模拟并发用户的数量。 4. **循环次数**:每个线程需要执行的循环次数,可以设置为无限循环。 5. **Ramp-up period**:规定所有线程启动的时间跨度,旨在平滑增加负载。 6. **定时器**:例如思考时间或...
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值