跳過到頁腳內容
.NET幫助

Polly Retry(對於開發者的運行原理)

妥善處理瞬時故障、超時和例外情況對於建立健壯且彈性強的應用程式至關重要。 Polly 是一個受歡迎的 .NET 庫,提供彈性和瞬時故障處理功能。 在其眾多功能中,“重試”是使用最廣泛的策略之一。

在本文中,我們將深入探討C# 中 Polly 的重試策略,探索其使用及配置選項,並提供實用的代碼範例。 此外,我們將結合 Polly 重試嘗試使用 IronPDF 庫生成的 PDF 生成表單請求結果的 PDF。

什麼是 Polly 重試?

Polly 重試是一項由 Polly 庫提供的策略,讓開發人員自動重試可能由於錯誤或瞬時故障導致的操作失敗。 瞬時故障是由於網絡故障、服務不可用或其他瞬時問題而發生的臨時錯誤。

有了 Polly 的重試策略,您可以為重試操作定義規則,包括最大重試次數、重試之間的延遲以及重試失敗請求的條件。這有助於構建能夠從臨時故障中恢復而不會崩潰或對最終用戶造成中斷的彈性應用程式。

開始使用 Polly 重試

在深入研究代碼範例之前,讓我們簡單了解如何在 C# 專案中安裝和配置 Polly。

安裝 Polly

您可以通過 NuGet Package Manager Console 使用以下命令安裝 Polly:

Install-Package Polly

或通過 .NET CLI:

dotnet add package Polly

添加 Polly 使用語句

在您的 C# 文件中,包含 Polly 命名空間:

using Polly;
using Polly;
Imports Polly
$vbLabelText   $csharpLabel

基本重試策略範例

讓我們從一個簡單的範例開始,重試模擬從遠程服務獲取數據的操作。我們將設置一個最多重試 3 次並且每次重試之間固定超時延遲 2 秒的重試策略。

using System;
using System.Net.Http;
using Polly;

namespace PollyRetryExample
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // Define a retry policy that handles HttpRequestException with a maximum of 3 retries
            var retryPolicy = Policy
                .Handle<HttpRequestException>() // Specify the exception type to handle
                .WaitAndRetry(
                    3, // Max retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2), // Fixed retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message);
                    });

            try
            {
                // Execute the action within the context of the retry policy
                retryPolicy.Execute(() =>
                {
                    FetchDataFromRemoteService();
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed after 3 retries: {0}", ex.Message);
            }
        }

        // Simulate fetching data that throws HttpRequestException
        public static void FetchDataFromRemoteService()
        {
            throw new HttpRequestException("Failed to fetch data from remote service");
        }
    }
}
using System;
using System.Net.Http;
using Polly;

namespace PollyRetryExample
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // Define a retry policy that handles HttpRequestException with a maximum of 3 retries
            var retryPolicy = Policy
                .Handle<HttpRequestException>() // Specify the exception type to handle
                .WaitAndRetry(
                    3, // Max retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2), // Fixed retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message);
                    });

            try
            {
                // Execute the action within the context of the retry policy
                retryPolicy.Execute(() =>
                {
                    FetchDataFromRemoteService();
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed after 3 retries: {0}", ex.Message);
            }
        }

        // Simulate fetching data that throws HttpRequestException
        public static void FetchDataFromRemoteService()
        {
            throw new HttpRequestException("Failed to fetch data from remote service");
        }
    }
}
Imports System
Imports System.Net.Http
Imports Polly

Namespace PollyRetryExample
	Public Class Program
		Public Shared Sub Main(ByVal args() As String)
			' Define a retry policy that handles HttpRequestException with a maximum of 3 retries
			Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetry(3, Function(retryAttempt) TimeSpan.FromSeconds(2), Sub(exception, timeSpan, retryCount, context)
				Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message)
			End Sub)

			Try
				' Execute the action within the context of the retry policy
				retryPolicy.Execute(Sub()
					FetchDataFromRemoteService()
				End Sub)
			Catch ex As Exception
				Console.WriteLine("Failed after 3 retries: {0}", ex.Message)
			End Try
		End Sub

		' Simulate fetching data that throws HttpRequestException
		Public Shared Sub FetchDataFromRemoteService()
			Throw New HttpRequestException("Failed to fetch data from remote service")
		End Sub
	End Class
End Namespace
$vbLabelText   $csharpLabel

在此範例中:

  • Handle<HttpRequestException>() 指定我們希望處理 HttpRequestException,如果發生則重試操作。
  • WaitAndRetry() 配置具有 3 次重試和重試之間 2 秒固定延遲(指定最大持續時間)的重試策略。
  • onRetry 委託在重試發生時記錄一條消息。

Polly 重試(它如何為開發人員工作):圖 1

高級重試策略配置

指數退避

指數退避是一種受歡迎的重試策略,其中請求與重試之間的延遲以指數方式增加。 Polly 提供了一種方便的方法來使用 WaitAndRetry() 實現指數退避。

var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3, // Max retry attempts
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)), // Exponential delay
        onRetry: (exception, timeSpan, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3, // Max retry attempts
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)), // Exponential delay
        onRetry: (exception, timeSpan, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetry(retryCount:= 3, sleepDurationProvider:= Function(attempt) TimeSpan.FromSeconds(Math.Pow(2, attempt)), onRetry:= Sub(exception, timeSpan, retryCount, context)
	Console.WriteLine($"Retry {retryCount} due to {exception.Message}")
End Sub)
$vbLabelText   $csharpLabel

Polly 重試(它如何為開發人員工作):圖 2

與斷路器結合的重試

結合重試與斷路器可以有效提升彈性,防止在服務持續故障時重複重試。 Polly 允許您輕鬆地結合重試和斷路器策略。

// Define a circuit breaker policy
var circuitBreakerPolicy = Policy
    .Handle<HttpRequestException>()
    .CircuitBreaker(
        exceptionsAllowedBeforeBreaking: 3, // Number of exceptions before breaking
        durationOfBreak: TimeSpan.FromSeconds(30), // Time circuit stays open
        onBreak: (ex, breakDelay) =>
        {
            Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.");
        },
        onReset: () =>
        {
            Console.WriteLine("Circuit reset.");
        });

// Define a retry policy
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3, // Max retry attempts
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(2), // Fixed retry delay
        onRetry: (exception, timeSpan, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });

// Combine both policies into a single policy wrap
var policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy);
// Define a circuit breaker policy
var circuitBreakerPolicy = Policy
    .Handle<HttpRequestException>()
    .CircuitBreaker(
        exceptionsAllowedBeforeBreaking: 3, // Number of exceptions before breaking
        durationOfBreak: TimeSpan.FromSeconds(30), // Time circuit stays open
        onBreak: (ex, breakDelay) =>
        {
            Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.");
        },
        onReset: () =>
        {
            Console.WriteLine("Circuit reset.");
        });

// Define a retry policy
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3, // Max retry attempts
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(2), // Fixed retry delay
        onRetry: (exception, timeSpan, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });

// Combine both policies into a single policy wrap
var policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy);
' Define a circuit breaker policy
Dim circuitBreakerPolicy = Policy.Handle(Of HttpRequestException)().CircuitBreaker(exceptionsAllowedBeforeBreaking:= 3, durationOfBreak:= TimeSpan.FromSeconds(30), onBreak:= Sub(ex, breakDelay)
			Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.")
End Sub, onReset:= Sub()
			Console.WriteLine("Circuit reset.")
End Sub)

' Define a retry policy
Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetry(retryCount:= 3, sleepDurationProvider:= Function(attempt) TimeSpan.FromSeconds(2), onRetry:= Sub(exception, timeSpan, retryCount, context)
	Console.WriteLine($"Retry {retryCount} due to {exception.Message}")
End Sub)

' Combine both policies into a single policy wrap
Dim policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy)
$vbLabelText   $csharpLabel

在此範例中:

  • CircuitBreaker() 定義在 3 次例外後中斷的斷路器策略,並保持開放 30 秒。
  • Policy.Wrap() 將斷路器和重試策略結合成一個單一策略。

Polly 重試(它如何為開發人員工作):圖 3

IronPDF 简介

IronPDF C# PDF 庫概覽 是一個強大的 C# 庫,讓開發人員能夠在 .NET 應用程式中創建、編輯和操作 PDF 文檔。 無論您需要創建發票、報告或任何其他類型的 PDF 文檔,IronPDF 提供直觀的 API 簡化了這一過程。

使用 IronPDF,您可以輕鬆將 HTML、CSS 甚至 ASP.NET 網頁轉換為 PDF,使其成為廣泛應用場景的多功能工具。 此外,它還提供高級功能,比如向 PDF 添加文本、圖像和交互元素,以及用加密和數字簽名保護它們。

IronPDF 在HTML 到 PDF轉換方面表現出色,確保精確保留原始佈局和樣式。 它非常適合從基於網頁的內容生成 PDF,例如報告、發票和文檔。 IronPDF 支持將 HTML 文件、URL 和原始 HTML 字符串轉換為高質量的 PDF 文件。

using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
Imports IronPdf

Friend Class Program
	Shared Sub Main(ByVal args() As String)
		Dim renderer = New ChromePdfRenderer()

		' 1. Convert HTML String to PDF
		Dim htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>"
		Dim pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent)
		pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf")

		' 2. Convert HTML File to PDF
		Dim htmlFilePath = "path_to_your_html_file.html" ' Specify the path to your HTML file
		Dim pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath)
		pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf")

		' 3. Convert URL to PDF
		Dim url = "http://ironpdf.com" ' Specify the URL
		Dim pdfFromUrl = renderer.RenderUrlAsPdf(url)
		pdfFromUrl.SaveAs("URLToPDF.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

Polly 重試與 IronPDF

在使用 IronPDF 時,可能會遇到需要從外部資源提取數據或在生成 PDF 之前執行複雜操作的場景。

在這種情況下,您可能會遇到會導致 PDF 生成失敗的瞬時故障或臨時問題。 為了優雅地處理這些瞬時故障,您可以將 Polly 重試與 IronPDF 結合使用。

安裝 IronPDF 和 Polly

在開始之前,確保在專案中安裝 IronPDF NuGet 包。

Install-Package IronPdf

將 Polly 重試與 IronPDF 結合使用

讓我們看看一個範例,我們使用 Polly 重試來處理使用 IronPDF 生成 PDF 時的瞬時故障。 在下面的範例中,我們將模擬從外部 API 提取數據,然後基於該數據生成 PDF。 如果發生故障,我們將使用 Polly Retry 執行數據提取操作。

using System;
using System.Net.Http;
using System.Threading.Tasks;
using IronPdf;
using Polly;

namespace IronPdfWithPollyRetry
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            // Define a retry policy with async capability
            var retryPolicy = Policy
                .Handle<HttpRequestException>() // Specify exception type to handle
                .WaitAndRetryAsync(
                    3, // Retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2), // Calculated retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry " + retryCount + " due to " + exception.Message);
                    });

            // Execute the retry policy asynchronously
            var pdf = await retryPolicy.ExecuteAsync(async () =>
            {
                var data = await FetchDataFromExternalApiAsync(); // Fetch data from an external source
                return GeneratePdfFromData(data); // Generate PDF using fetched data
            });

            pdf.SaveAs("GeneratedDocument.pdf");
        }

        // Simulate fetching data from an external API
        static async Task<string> FetchDataFromExternalApiAsync()
        {
            await Task.Delay(100); // Simulate delay
            throw new HttpRequestException("Failed to fetch data from external API");
        }

        // Generate PDF using IronPDF based on the fetched data
        static PdfDocument GeneratePdfFromData(string data)
        {
            var htmlContent = "<html><body><h1>Data: " + data + "</h1></body></html>";
            var renderer = new ChromePdfRenderer();
            return renderer.RenderHtmlAsPdf(htmlContent);
        }
    }
}
using System;
using System.Net.Http;
using System.Threading.Tasks;
using IronPdf;
using Polly;

namespace IronPdfWithPollyRetry
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            // Define a retry policy with async capability
            var retryPolicy = Policy
                .Handle<HttpRequestException>() // Specify exception type to handle
                .WaitAndRetryAsync(
                    3, // Retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2), // Calculated retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry " + retryCount + " due to " + exception.Message);
                    });

            // Execute the retry policy asynchronously
            var pdf = await retryPolicy.ExecuteAsync(async () =>
            {
                var data = await FetchDataFromExternalApiAsync(); // Fetch data from an external source
                return GeneratePdfFromData(data); // Generate PDF using fetched data
            });

            pdf.SaveAs("GeneratedDocument.pdf");
        }

        // Simulate fetching data from an external API
        static async Task<string> FetchDataFromExternalApiAsync()
        {
            await Task.Delay(100); // Simulate delay
            throw new HttpRequestException("Failed to fetch data from external API");
        }

        // Generate PDF using IronPDF based on the fetched data
        static PdfDocument GeneratePdfFromData(string data)
        {
            var htmlContent = "<html><body><h1>Data: " + data + "</h1></body></html>";
            var renderer = new ChromePdfRenderer();
            return renderer.RenderHtmlAsPdf(htmlContent);
        }
    }
}
Imports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports IronPdf
Imports Polly

Namespace IronPdfWithPollyRetry
	Public Class Program
		Public Shared Async Function Main(ByVal args() As String) As Task
			' Define a retry policy with async capability
			Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetryAsync(3, Function(retryAttempt) TimeSpan.FromSeconds(2), Sub(exception, timeSpan, retryCount, context)
				Console.WriteLine("Retry " & retryCount & " due to " & exception.Message)
			End Sub)

			' Execute the retry policy asynchronously
			Dim pdf = Await retryPolicy.ExecuteAsync(Async Function()
				Dim data = Await FetchDataFromExternalApiAsync() ' Fetch data from an external source
				Return GeneratePdfFromData(data) ' Generate PDF using fetched data
			End Function)

			pdf.SaveAs("GeneratedDocument.pdf")
		End Function

		' Simulate fetching data from an external API
		Private Shared Async Function FetchDataFromExternalApiAsync() As Task(Of String)
			Await Task.Delay(100) ' Simulate delay
			Throw New HttpRequestException("Failed to fetch data from external API")
		End Function

		' Generate PDF using IronPDF based on the fetched data
		Private Shared Function GeneratePdfFromData(ByVal data As String) As PdfDocument
			Dim htmlContent = "<html><body><h1>Data: " & data & "</h1></body></html>"
			Dim renderer = New ChromePdfRenderer()
			Return renderer.RenderHtmlAsPdf(htmlContent)
		End Function
	End Class
End Namespace
$vbLabelText   $csharpLabel

這段 C# 代碼演示了如何使用 Polly 庫與 IronPDF 結合實現重試策略來生成 PDF 文檔。 Main 方法使用 Polly 的 WaitAndRetryAsync 方法初始化重試策略。

該策略指定應處理 HttpRequestException,並在初次嘗試和重試之間的延遲為 2 秒的情況下最多重試 3 次。 如果發生重試失敗,則會在控制台上打印一條消息,指示重試嘗試次數及例外消息。

Main 方法內,重試策略邏輯使用 retryPolicy.ExecuteAsync() 異步執行。 在此執行中,兩個異步操作被串聯在一起:FetchDataFromExternalApiAsync()GeneratePdfFromData(data)

如果 FetchDataFromExternalApiAsync() 失敗(由於故意設置模擬例外情況),重試策略將捕獲 HttpRequestException,記錄重試嘗試並重試操作。

FetchDataFromExternalApiAsync() 方法模擬從外部 API 提取數據,並有意拋出 HttpRequestException 以模擬請求失敗。

Polly 重試(它如何為開發人員工作):圖 4

結論

總之,Polly 的重試策略在處理瞬時故障和確保 C# 應用程式的可靠性方面非常有價值。 其重試次數、延遲和條件的配置靈活性允許開發人員根據具體需求定制彈性策略。

無論是單獨使用還是與IronPDF等庫結合使用,Polly 都能幫助創建在暫時故障中優雅恢復的應用程式,從而提高用戶體驗和軟體的可靠性。

通過集成 Polly 的重試功能,開發人員可以構建更有彈性的系統,並擁有適應和從瞬態問題中恢復的能力,最終可以提升應用程式的整體質量和可靠性。

IronPDF 是市場上最好的 C# PDF 庫,還提供 IronPDF 試用許可證,價格從 $799 美元起。

要了解使用 IronPDF 進行 HTML 到 PDF 轉換,請訪問以下IronPDF HTML 到 PDF 轉換教程

常見問題解答

什麼是C#中的Polly重試?

Polly重試是C#中Polly庫的一個功能,允許開發人員自動重試由於暫時問題如網路故障或服務不可用導致失敗的操作。這有助於通過優雅處理瞬態故障來構建具韌性的應用程式。

如何使用Polly實現基本的重試策略?

可以在Polly中通過處理如HttpRequestException等異常來實現基本重試策略,並將其設置為最多重試三次,每次嘗試之間固定延遲兩秒。

Polly中的指數退避有什麼意義?

Polly中的指數退避用於指數增加重試間的延遲,這有助於在故障期間減少服務的負載。這可以使用Polly的WaitAndRetry方法來實現,該方法基於指數增長計算延遲。

如何在C#項目中安裝Polly?

可以通過NuGet包管理器控制台使用命令Install-Package Polly或通過.NET CLI使用dotnet add package Polly在C#項目中安裝Polly。

Polly的重試策略可以與其他韌性策略結合嗎?

是的,Polly允許您將其重試策略與其他韌性策略(如斷路器)結合使用,通過Policy.Wrap方法增強應用程式的韌性,並防止服務持續失敗時重複重試。

怎樣在 C# 中將 HTML 轉換為 PDF?

可以使用IronPDF的方法如RenderHtmlAsPdf將HTML字串轉換為PDF。IronPDF還支持將HTML文件和網頁(包括CSS)轉換為PDF格式。

為什麼Polly的重試策略對於C#應用程式很重要?

Polly的重試策略對於處理C#應用程式中的瞬態故障至關重要,這確保了健壯性並通過允許系統從暫時故障中恢復而不崩潰來改善用戶體驗。

如何在PDF生成過程中實現重試策略?

在生成PDF時,可以使用Polly來實現重試策略以處理瞬態故障。通過將Polly的重試能力與IronPDF整合,可以在臨時網絡或服務問題的情況下多次嘗試PDF操作。

如何安裝像IronPDF這樣的C# PDF庫?

IronPDF可以通過NuGet包管理器使用命令Install-Package IronPdf安裝,允許在您的C#應用程式中創建、編輯和操控PDF文件。

使用IronPDF生成PDF的好處是什麼?

IronPDF為在.NET應用程式中創建和操控PDF文件提供了強大的功能。它支持將HTML、CSS和網頁轉換為PDF,添加文字和圖像,並使用加密保護文件。

Curtis Chau
技術作家

Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。

除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。