主頁 > .NET開發 > 使用MASA Blazor開發一個標準的查詢表格頁

使用MASA Blazor開發一個標準的查詢表格頁

2022-03-11 06:00:28 .NET開發

前言

大家好,我是開源專案 MASA Blazor 主要開發者之一,如果你還不了解MASA Blazor,可以訪問我們的 官網 和博客 《初識MASA Blazor》 一探究竟,簡單來說,MASA Blazor 是一個基于 Material Design 設計語言的 Blazor 組件庫,dotNET開發者只需或者甚至不需要懂得 javascript 就能開發一個企業級中后臺系統,

我這次分享的主題是《使用MASA Blazor開發一個標準的查詢表格頁》,我會先從創建專案開始手擼一個沒有任何技巧的查詢表格頁,然后我會分享一些技巧和封裝的組件,實作快速開發,

手擼查詢表格頁

創建應用程式

關于如何安裝MASA Blazor模板,請移步 MASA.Blazor快速入門,

  1. 首先通過MASA Blazor模板默認的Server專案,專案命名為 MasaBlazorStandardTablePage

    dotnet new --install MASA.Template
    dotnet new masab -o MasaBlazorStandardTablePage
    
  2. 通過CLI運行應用程式,或直接通過vs啟動專案,

    cd MasaBlazorStandardTablePage
    dotnet run
    
  3. 啟動成功后切換到 Fetch data 頁面,此頁面展示了一個簡單的使用了 MDataTable 的表格,

    default-fetch-data.png

支持單個查詢條件和搜索

讓我們從最簡單的單個條件查詢開始,

將隨機資料替換成模擬資料

  1. 修改 WeatherForecastService,將隨機資料替換成死資料以便支持查詢功能,下面的代碼更新了資料來源和 GetForecastAsync 查詢方法,

        public class WeatherForecastService
        {
            private readonly List<WeatherForecast> _data = https://www.cnblogs.com/capdiem/p/new()
            {
                new() { Date = DateTime.Now.AddDays(-1), TemperatureC = 23, Summary ="Freezing" },
                new() { Date = DateTime.Now.AddDays(-1), TemperatureC = -10, Summary = "Bracing" },
                new() { Date = DateTime.Now.AddDays(-1), TemperatureC = 37, Summary = "Chilly" },
                new() { Date = DateTime.Now.AddDays(-2), TemperatureC = 29, Summary = "Cool" },
                new() { Date = DateTime.Now.AddDays(-3), TemperatureC = 11, Summary = "Mild" },
                new() { Date = DateTime.Now.AddDays(-4), TemperatureC = 35, Summary = "Warm" },
                new() { Date = DateTime.Now.AddDays(-5), TemperatureC = 41, Summary = "Balmy" },
                new() { Date = DateTime.Now.AddDays(-5), TemperatureC = -13, Summary = "Hot" },
                new() { Date = DateTime.Now.AddDays(-6), TemperatureC = 23, Summary = "Sweltering" },
                new() { Date = DateTime.Now.AddDays(-7), TemperatureC = 2, Summary = "Scorching" },
            };
            
            public Task<WeatherForecast[]> GetForecastAsync()
            {
                IEnumerable<WeatherForecast> res = _data.AsQueryable();
    
                return Task.FromResult(res.ToArray());
            }
        }
    
  2. 同時修改 FetchData.razor,因為 WeatherForecastService.GetForecastAsync() 洗掉了 startDate 入參,

    protected override async Task OnInitializedAsync()
    {
        await Task.Delay(1000); // 模擬真實環境,觸發Loading效果
        forecasts = await ForecastService.GetForecastAsync(); // here
    }
    

添加查詢輸入框和搜索按鈕

  1. FetchData.razor 頁面中的 <p> 標簽下添加以下代碼

    <MRow >
        <MCol Cols="12">
            <MTextField @bind-Value="https://www.cnblogs.com/capdiem/p/summary"
                        Dense
                        HideDetails="@("auto")"
                        Label="Summary"
                        Outlined>
            </MTextField>
        </MCol>
        <MCol Cols="12" >
            <MSpacer></MSpacer>
            <MButton Color="primary" OnClick="OnSearch">搜索</MButton>
        </MCol>
    </MRow>
    
    @code {
        private string summary;
    
        private async Task OnSearch()
        {
            forecasts = await ForecastService.GetForecastAsync(summary);
        }
    }
    
    • Line 3,17

      定義了一個 string 型別的名為 summary 的變數,雙向系結給了 MTextField 組件,MTextFiled 除了 @bind-Value 屬性用于設定雙向系結,其他屬性的含義請閱讀 檔案,

    • Line 12

      定義了一個搜索按鈕,用于觸發查詢,

  2. 修改 WeatherForecastService.GetForecastAsync 方法,增加 summary 入參,并支持查詢,

    public Task<WeatherForecast[]> GetForecastAsync(string? summary = null)
    {
        IEnumerable<WeatherForecast> res = _data.AsQueryable();
    
        if (!string.IsNullOrEmpty(summary))
        {
            res = res.Where(item => item.Summary.Contains(summary));
        }
    
        return Task.FromResult(res.ToArray());
    }
    

summary-query.gif

支持多個查詢條件和重置

現在讓我們再添加一個高溫預警的選擇框來查詢不同高溫預警狀態的資料,

更新 WeatherForecastService 以支持根據高溫預警篩選資料

public Task<WeatherForecast[]> GetForecastAsync(string? summary = null, WarningSigns? warningSigns = null)
{
    IEnumerable<WeatherForecast> res = _data.AsQueryable();

    if (!string.IsNullOrEmpty(summary))
    {
        res = res.Where(item => item.Summary.Contains(summary));
    }

    if (warningSigns.HasValue)
    {
        res = warningSigns switch
        {
            WarningSigns.Yellow => res.Where(item => item.TemperatureC >= 35 && item.TemperatureC < 37),
            WarningSigns.Orange => res.Where(item => item.TemperatureC >= 37 && item.TemperatureC < 39),
            WarningSigns.Red => res.Where(item => item.TemperatureC >= 39),
            _ => res
        };
    }

    return Task.FromResult(res.ToArray());
}

增加高溫預警選擇框

  1. Data 目錄下添加名為 WarningSigns 的列舉,

    public enum WarningSigns
    {
        [Description("高溫黃色預警 35℃")]
        Yellow = 1,
        [Description("高溫橙色預警 37℃")]
        Orange,
        [Description("高溫紅色預警 39℃")]
        Red
    }
    
  2. 引入 Masa.Utils.Enums 包,此包提供的 GetEnumObjectList 方法能輕松的將列舉的 Description 和列舉值用于 MSelect 組件的 Items

    dotnet add package Masa.Utils.Enums
    
  3. 更新 FetchData.razor

    <MRow >
            <MCol Cols="12" Sm="6">
            <MTextField @bind-Value="https://www.cnblogs.com/capdiem/p/@summary"
                        Label="Summary"
                        Dense
                        HideDetails="@("auto")"
                        Outlined>
            </MTextField>
        </MCol>
        <MCol Cols="12" Sm="6">
            <MSelect @bind-Value="https://www.cnblogs.com/capdiem/p/warningSigns"
                    Items="@(Enum<WarningSigns>.GetEnumObjectList<WarningSigns>())"
                    ItemText="item => item.Name"
                    ItemValue="https://www.cnblogs.com/capdiem/p/item => item.Value"
                    TValue="https://www.cnblogs.com/capdiem/p/WarningSigns?"
                    TItem="EnumObject<WarningSigns>"
                    TItemValue="https://www.cnblogs.com/capdiem/p/WarningSigns"
                    Label="高溫警告"
                    Clearable
                    Dense
                    HideDetails="@("auto")"
                    Outlined>
            </MSelect>
        </MCol>
        <MCol Cols="12" >
            <MSpacer></MSpacer>
            <MButton  OnClick="OnReset">重置</MButton>
            <MButton Color="primary" OnClick="OnSearch">搜索</MButton>
        </MCol>
    </MRow>
    
    @code {
        private WarningSigns? warningSigns;
        
        private Task OnReset()
        {
            summary = null;
            warningSigns = null;
            return OnSearch();
        }
    
        private async Task OnSearch()
        {
            forecasts = await ForecastService.GetForecastAsync(summary, warningSigns);
        }
    }
    
    • Line 2,10

    通過設定 Sm="6" 可以讓螢屏尺寸大于768px時一行占兩個 MCol ,實作 MTextFieldMSelect 并排顯示,

    • Line 11-23,33,44

    第33行定義 warningSigns 變數用于接收 MSelect 選中的值,當然也可以通過設定值更新 MSelect 選中的值,只要設定了 @bind-Value 雙向系結就行,就像第11行那樣,第12行使用了 Masa.Utils.Enums 提供的方法,回傳了一個包含Name(Description)和Value(列舉值)的串列,賦值給了 MSelect.Items ,第44行將 warningSigns 的傳給查詢介面,

    • Line 27,35-40

    此處定義了一個重置按鈕,用于清空所有查詢輸入框的內容并重繪表格,

select-query.gif

支持鍵入回車或選擇后觸發查詢

后來測驗小姐姐說你這太難用了,回車不能觸發搜索,選擇完也不能觸發搜索,好吧好吧,我們現在加上,

鍵入回車后觸發

原理即捕捉 OnKeyDown 事件是否點擊了 Enter 鍵,

<MTextField @bind-Value="https://www.cnblogs.com/capdiem/p/@summary"
            OnKeyDown="HandleOnKeyDown"
            Label="Summary"
            Dense
            HideDetails="@("auto")"
            Outlined>
</MTextField>

@code {
    private async Task HandleOnKeyDown(KeyboardEventArgs args)
    {
        if (args.Code == "Enter")
        {
            // 等待156毫秒,預防輸入的值在更新到變數之前按下Enter鍵
            await Task.Delay(156);

            await OnSearch();
        }
    }
}
  • Line 2

    HandleOnKeyDown 系結到 MTextFieldOnKeyDown 事件,

  • Line 10-17

    通過判斷 KeyboardEventArgsCode 值是否為 Enter 來觸發搜索,第14行等待156毫秒是為了等待 summary 的值已經是輸入過后的值,

選擇后觸發查詢

<MSelect @bind-Value="https://www.cnblogs.com/capdiem/p/warningSigns"
    	 Items="@(Enum<WarningSigns>.GetEnumObjectList<WarningSigns>())"
    	 ItemText="item => item.Name"
    	 ItemValue="https://www.cnblogs.com/capdiem/p/item => item.Value"
    	 TValue="https://www.cnblogs.com/capdiem/p/WarningSigns?"
    	 TItem="EnumObject<WarningSigns>"
    	 TItemValue="https://www.cnblogs.com/capdiem/p/WarningSigns"
    	 Label="高溫警告"
    	 OnSelectedItemUpdate="OnSearch"
    	 Clearable
         Dense
         HideDetails="@("auto")"
    	 Outlined>
</MSelect>
  • Line 9

    當選擇項更新時(OnSelectedItemUpdate)直接呼叫 OnSearch 方法,觸發查詢,此處不用像上面處理 OnKeyDown 那樣等待156毫秒,因為 OnSelectedItemUpdate 是在 warningSigns 更新后觸發的,

點擊清空圖示觸發查詢

很簡單,只要給 MTextFieldMSelect 組件添加以下屬性:

Clearable
OnClearClick="OnSearch"

enter-query.gif

加點Loading影片可好?

好!

<MButton Color="primary" 
    	 Loading="searching" 
    	 OnClick="HandleOnSearch">
    搜索
</MButton>
...

<MDataTable Headers="_headers" Items="forecasts" 
            Loading="loading" 
            ItemsPerPage="5" >
...
    
@code {
    private bool loading;
    private bool searching;
    
    private async Task HandleOnSearch()
    {
        searching = true;

        await OnSearch();

        searching = false;
    }
    
    private async Task OnSearch()
    {
        loading = true;
        
        await Task.Delay(1000);
        forecasts = await ForecastService.GetForecastAsync(summary, warningSigns);

        loading = false;
    }
}
  • Line 2-3,15,17-24

    新增 searching 變數用于控制搜索按鈕的 Loading 狀態,同時新增了 HandleOnSearch 代替原來的 OnSearch 是為了單獨控制點擊搜索按鈕的影片,

  • Line 9,14,28,33

    新增 loading 變數用于控制 MDataTableLoading 狀態,OnSearch 方法塊中在介面請求前后設定 loading 的值,

loading.gif

表的行操作和自定義列樣式

因為篇幅限制,我就不一一把代碼貼出來了,具體代碼請查閱 原始碼 接下來我將針對Table寫一些常見的代碼,如行操作和自定義列樣式,

table.gif

封裝組件和技巧

我本應該用這節分享的內容將上面的例子重構的程序寫出來,但感徑訓使得本文太冗長,重構后的代碼我也會上傳到 Github 上,

封裝組件

試想一下,當你被分配到好幾個模塊,每個模塊都有至少一個查詢表格頁,你會如何開發?你大概會說復制最合適的代碼檔案,然后重命名檔案名,重命名相應的變數,修修改改就完行了,當然這是一個方法,但不優雅,那優雅的方式是什么,是封裝,我有段時間在全職開發 MASA.Blazor 組件庫,后面因為業務需求分配到了IoT專案幫助Blazor后臺系統的研發和 MASA.Blazor 的實踐,在開發IoT專案時,經常會看見相同的代碼分布在相同的類中,我試著優化重構這些代碼,并從查詢表格頁中抽離封裝了以下幾個組件:

  • Filters:接收OnSearch引數代理查詢,通過context提供onEnteronSearch方法供單個查詢組件使用,
  • PageHeader:一個標準的頁頭,包括了標題、副標題、搜索按鈕,并提供Filters組件的能力,
  • Actions:提供一組操作按鈕,默認展示前兩個,后面的按鈕會移動到MMenu中顯示,
  • BlockText:將相同型別的兩個資料并列顯示,
  • ColorChip:提供有限的顏色串列生成帶淺色字體的MChip
  • CopyableText:在文本后提供可以復制內容的圖示按鈕,
  • DateTimePicker:提高帶時分秒選擇器的彈出層時間選擇器,
  • EllipsisText:根據父級盒子的寬度自動截斷文本,
  • GenericColumnRender:渲染DateTime、列舉、bool和其他型別值,可以用于MDataTableItemColContentDefinitionsDetailContent

PageHeader組件作為 MASA.Blazor 預置組件的一部分已經發布,其他提及的組件還沒有并入 MASA.Blazor 主庫,如果你想要使用或參考,可以訪問 MASA.Blazor.Experimental.Components,關于預置組件和實驗性組件的詳細介紹和使用的文章,后面會由其他同事撰寫和發布,請大家帶多多關注!

MASA.Blazor.Experimental.Components 是一個實驗性組件庫,這意味著該庫的API和功能可能會被重新設計,不過隨著實驗性組件的功能不斷完善和穩定,會隨著 MASA.Blazor 版本的更新而并入主庫,

技巧

善用基類

Blazor的組件其實也是一個類,它默認繼承自 ComponentBase 并提供了許多虛擬方法,我們可以重寫它們來影回應用程式的行為,而這些方法通過繼承機制給所有Blazor組件使用,

在實際開發中,我會發現幾乎每個頁面都會注入 NavigationManagerIJsRunTime 和其他可能存在的業務服務,或者會使用某些共同使用的組件,那我們可以在繼承 ComponentBase 的基礎上再寫一個已經使用了這些服務和組件的基類,

按架構可以創建專門給 @page 組件用的 PageComponentBase 和單純封裝功能的 PureComponentBase
按業務分類就得看情況了,因為業務更加具體,基類里通常會有注入 HttpClient 或者同型別業務服務,以及任何共同使用的代碼,

SetParametersAsync

SetParametersAsync sets parameters supplied by the component's parent in the render tree or from route parameters.

只需知道每當父級呈現時,都會執行此方法,這意味著它是指定默認引數值的正確位置,
拿前面的例子來說,在使用 MTextFieldMSelect 時都會設定以下代碼來維持相同的外觀和行為:

Clearable
Dense
HideDetails="@("auto")"
Outlined

那么與其每次都要寫一遍,不如利用 SetParametersAsync 的特性把這些默認引數提前設定:

public class DefaultTextField<TValue> : MTextField<TValue>
{
    public override async Task SetParametersAsync(ParameterView parameters)
    {
        Clearable = true;
        Dense = true;
        HideDetails = "auto";
        Outlined = true;

        await base.SetParametersAsync(parameters);
    }
}

public class DefaultSelect<TItem, TItemValue, TValue> : MSelect<TItem, TItemValue, TValue>
{
    public override async Task SetParametersAsync(ParameterView parameters)
    {
        Clearable = true;
        Dense = true;
        HideDetails = "auto";
        Outlined = true;
        
        await base.SetParametersAsync(parameters);
    }
}
<DefaultTextField @bind-Value="https://www.cnblogs.com/capdiem/p/@summary"
                  OnKeyDown="@context.onEnter"
                  OnClearClick="@context.onSearch"
                  Label="Summary">
</DefaultTextField>

<DefaultSelect @bind-Value="https://www.cnblogs.com/capdiem/p/warningSigns"
               Items="@(Enum<WarningSigns>.GetEnumObjectList<WarningSigns>())"
               ItemText="item => item.Name"
               ItemValue="https://www.cnblogs.com/capdiem/p/item => item.Value"
               TValue="https://www.cnblogs.com/capdiem/p/WarningSigns?"
               TItem="EnumObject<WarningSigns>"
               TItemValue="https://www.cnblogs.com/capdiem/p/WarningSigns"
               Label="高溫警告"
               OnSelectedItemUpdate="@context.onSearch"
               OnClearClick="@context.onSearch">
</DefaultSelect>

after.gif

未來的計劃

未來我們團隊將繼續優化各個組件的性能,完成缺失的組件,解決BUG問題,完善檔案等,另外,我們也計劃出Blazor相關的教程和分享文章,敬請期待,

感謝閱讀!

資源

  • 原始碼
    • ?https://github.com/capdiem/MasaBlazorStandardTablePage
  • 參考
    • https://blazor.masastack.com/
    • https://github.com/BlazorComponent/Masa.Blazor
    • https://github.com/capdiem/MASA.Blazor.Experimental.Components

開源地址

MASA.BuildingBlocks:https://github.com/masastack/MASA.BuildingBlocks

MASA.Contrib:https://github.com/masastack/MASA.Contrib

MASA.Utils:https://github.com/masastack/MASA.Utils

MASA.EShop:https://github.com/masalabs/MASA.EShop

MASA.Blazor:https://github.com/BlazorComponent/MASA.Blazor

如果你對我們的 MASA Framework 感興趣,無論是代碼貢獻、使用、提 Issue,歡迎聯系我們

16373211753064.png

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/440500.html

標籤:ASP.NET

上一篇:在ggplot中給出特定的中斷

下一篇:C#-2 C#程式

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more