使用C#(winform,Console...)调用通义千问大模型(灵积大模型)

本文介绍了如何使用C#编程语言通过HTTP请求调用阿里云的Qwen大语言模型,提供了一个完整的示例代码,包括API密钥认证和请求发送过程。
Qwen3-8B

Qwen3-8B

文本生成
Qwen3

Qwen3 是 Qwen 系列中的最新一代大型语言模型,提供了一整套密集型和专家混合(MoE)模型。基于广泛的训练,Qwen3 在推理、指令执行、代理能力和多语言支持方面取得了突破性进展

要如何与自己的工作相互结合,解决业务问题?我想第一步先考虑用熟悉的语言来调用大语言模型吧。

官方没有直接给出具体的示例代码,以下是完整代码,喜欢点赞收藏转发吧,记得给留个来源说明。通过调用http请求:

using System;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;
using System.Threading.Tasks;
using System.Net.Http.Headers;

public class Program
{
    private readonly static string _requestUri = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation";
    private readonly static string _apiKey = "密钥"; // 请替换为您的阿里云密钥信息
    private readonly static string _model = "qwen-max";

    private static async Task CallQWen(string question)
    {
        using (var client = new HttpClient())
        {
            // 创建模型类
            var requestObj = new QianWenRequest
            {
                Model = _model,
                Input = new Input
                {
                    Prompt = question
                }
            };

            var settings = new JsonSerializerSettings
            {
                Formatting = Formatting.Indented,
                StringEscapeHandling = StringEscapeHandling.EscapeNonAscii
            };

            // 将对象序列化为JSON字符串
            string requestJson = JsonConvert.SerializeObject(requestObj, settings);
            Console.WriteLine(requestJson);

            var request = new HttpRequestMessage(HttpMethod.Post, _requestUri);
            //定义Body
            var content = new StringContent(requestJson.ToLower(), Encoding.UTF8, "application/json");
            request.Content = content;

            //定义header
            request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); // 正确做法
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", $"{_apiKey}");

            var response = await client.SendAsync(request);

            if (response.IsSuccessStatusCode)
            {
                var responseBody = await response.Content.ReadAsStringAsync();
                
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("通义千问的回答:");
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine(responseBody);
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine($"请求失败,状态码:{response.StatusCode}");
                Console.ForegroundColor = ConsoleColor.White;
            }
        }
    }

    static async Task Main(string[] args)
    {
        Console.OutputEncoding = System.Text.Encoding.UTF8;
        // 对于.NET Core 3.0+
        Console.InputEncoding = System.Text.Encoding.UTF8;

        while (true)
        {
            // 设置前景色为绿色
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("请输入您的问题(按'q'或者使用ctrl+c退出):");
            Console.ForegroundColor = ConsoleColor.White;

            string userInput = Console.ReadLine();

            Console.WriteLine("输入的内容为:" + userInput);
            if (userInput.ToLower() == "q")
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("退出程序...");
                Console.ForegroundColor = ConsoleColor.White;
                break;  //用户输入'q'时跳出循环,结束程序
            }
            
            //调用定义好的函数进行对话并处理响应
            await CallQWen(userInput);
        }
    }
}

public class QianWenRequest
{
    public string Model { get; set; }
    public Input Input { get; set; }
}

public class Input
{
    public string Prompt { get; set; }
}

您可能感兴趣的与本文相关的镜像

Qwen3-8B

Qwen3-8B

文本生成
Qwen3

Qwen3 是 Qwen 系列中的最新一代大型语言模型,提供了一整套密集型和专家混合(MoE)模型。基于广泛的训练,Qwen3 在推理、指令执行、代理能力和多语言支持方面取得了突破性进展

<think>我们正在处理一个WinForms应用程序,目标是在其中捕获Console.WriteLine的输出。根据引用[1]中的代码,用户尝试在WinForm使用Console.WriteLine,但默认情况下这些输出不会显示在窗体上,而是会弹出一个控制台窗口(除非在项目设置中配置为Windows应用程序)。因此,我们需要重定向控制台输出到WinForm的某个控件(如文本框)中。 根据之前的回答,我们有几种方法可以重定向控制台输出。这里我们选择重定向到自定义的TextWriter,并将输出发送到文本框。 步骤: 1. 创建一个自定义的TextWriter,它可以将写入的字符串转发到文本框。 2. 在窗体初始化时(例如在构造函数或Load事件中)将Console.Out设置为这个自定义TextWriter。 3. 注意线程安全,因为Console.WriteLine可能被任何线程调用,而文本框的更新必须在UI线程上执行。 另外,引用[2]提到可以使用Debug.WriteLine,但这会将输出发送到调试器,而不是窗体上的控件。如果用户希望捕获Console.WriteLine,那么我们需要重定向Console.Out。 引用[3]展示了如何捕获外部进程的输出,但这里我们是要捕获当前应用程序内的Console.WriteLine,所以不适用。 因此,我们实现一个自定义的TextWriter: 自定义TextWriter类(可以内嵌在窗体类中): - 重写Write和WriteLine方法。 - 在方法中,将文本追加到文本框。注意跨线程调用。 示例代码: 在Form1类中: - 我们定义一个类`ControlWriter`继承`TextWriter`,它将文本框作为目标。 - 在窗体初始化时,将Console.Out设置为这个ControlWriter的实例。 注意:由于Console.Out是静态的,重定向后会影响整个应用程序的Console.WriteLine输出。因此,在窗体关闭时,最好恢复原来的输出流(如引用[1]中提到的FreeConsole,但这里我们不需要FreeConsole,因为重定向不会创建控制台窗口,而是替换了输出流。恢复原来的输出流可以避免资源泄露和异常)。 具体步骤: 1. 在窗体类中定义自定义TextWriter: ```csharp public class ControlWriter : TextWriter { private Control _control; public ControlWriter(Control control) { _control = control; } public override Encoding Encoding => Encoding.UTF8; // 重写Write方法 public override void Write(string value) { // 追加文本到控件,需要跨线程安全 if (_control.InvokeRequired) { _control.Invoke(new Action<string>(Write), value); } else { _control.Text += value; } } // 重写WriteLine方法 public override void WriteLine(string value) { Write(value + Environment.NewLine); } } ``` 2. 在窗体初始化时重定向控制台输出: ```csharp public Form1() { InitializeComponent(); // 保存原来的输出流 _originalOutput = Console.Out; // 重定向到我们自定义的TextWriter,这里我们假设有一个文本框textBox1 Console.SetOut(new ControlWriter(textBox1)); } ``` 3. 在窗体关闭时恢复原来的输出流: ```csharp protected override void OnFormClosing(FormClosingEventArgs e) { base.OnFormClosing(e); Console.SetOut(_originalOutput); // 恢复 } ``` 但是,上面的自定义TextWriter中,我们直接操作了控件的Text属性。对于多行文本,使用TextBox控件时,建议使用AppendText方法或者设置Multiline属性为true,并可能使用ScrollBars。另外,频繁追加文本时,直接设置Text属性可能会导致性能题(因为每次都要重绘),我们可以使用StringBuilder来优化,但这里为了简单,我们使用AppendText方法。 改进:我们可以修改自定义TextWriter,使用TextBox的AppendText方法(注意线程安全)。 修改后的ControlWriter: ```csharp public class ControlWriter : TextWriter { private TextBox _textBox; public ControlWriter(TextBox textBox) { _textBox = textBox; } public override Encoding Encoding => Encoding.UTF8; public override void Write(string value) { if (_textBox.InvokeRequired) { _textBox.Invoke(new Action<string>(Write), value); } else { _textBox.AppendText(value); } } public override void WriteLine(string value) { Write(value + Environment.NewLine); } } ``` 注意:这里我们指定了TextBox,因为我们知道要追加到文本框。如果窗体上有一个多行文本框(Multiline设置为true),那么输出将会自动换行。 使用示例: 在窗体上放置一个TextBox,命名为textBoxOutput,设置Multiline为true,并调整大小。 然后在窗体构造函数中: ```csharp public Form1() { InitializeComponent(); // 保存原来的输出流 _originalOutput = Console.Out; // 重定向到textBoxOutput Console.SetOut(new ControlWriter(textBoxOutput)); } ``` 这样,程序中所有Console.WriteLine的输出都会显示在这个文本框中。 另外,引用[1]中的InitializeConsole方法中调用Console.WriteLine,它会在窗体初始化时被调用,所以输出会显示在文本框中。同样,按钮点击事件中的Console.WriteLine也会被捕获。 注意:如果程序中有多个线程调用Console.WriteLine,由于我们使用了Invoke,所以是线程安全的。 完整代码示例: Form1.cs:</think>在 C# WinForm 应用程序中捕获 `Console.WriteLine()` 的输出,可以通过重定向标准输出流实现。以下是完整解决方案: ### 完整实现步骤 #### 1. 创建自定义 TextWriter ```csharp public class TextBoxWriter : TextWriter { private readonly TextBox _textBox; public TextBoxWriter(TextBox textBox) { _textBox = textBox; } public override Encoding Encoding => Encoding.UTF8; // 核心重写方法 public override void Write(string? value) { if (_textBox.InvokeRequired) // 跨线程安全处理 { _textBox.Invoke(new Action<string>(Write), value); } else { _textBox.AppendText(value); } } public override void WriteLine(string? value) { Write(value + Environment.NewLine); } } ``` #### 2.WinForm 中初始化重定向 ```csharp public partial class MainForm : Form { private TextWriter _originalOutput; // 保存原始输出流 public MainForm() { InitializeComponent(); InitializeConsoleRedirection(); } private void InitializeConsoleRedirection() { // 保存原始输出流 _originalOutput = Console.Out; // 重定向到文本框 Console.SetOut(new TextBoxWriter(txtConsoleOutput)); // 测试输出 Console.WriteLine("控制台输出已重定向到文本框"); Console.WriteLine($"当前时间: {DateTime.Now:HH:mm:ss}"); } // 按钮点击示例 private void btnTest_Click(object sender, EventArgs e) { Console.WriteLine("按钮被点击 - " + DateTime.Now.ToString("T")); } // 窗体关闭时恢复原始输出 protected override void OnFormClosing(FormClosingEventArgs e) { Console.SetOut(_originalOutput); // 恢复原始输出流 base.OnFormClosing(e); } } ``` #### 3. 窗体设计要点 1. 添加多行文本框 `txtConsoleOutput`: - 设置 `Multiline = true` - 设置 `ScrollBars = Vertical` 2. 添加测试按钮 `btnTest` ### 关键说明 1. **跨线程处理** 使用 `Control.Invoke` 确保线程安全,避免跨线程操作 UI 控件的题[^1]。 2. **性能优化** 使用 `AppendText` 代替直接修改 `Text` 属性,避免大文本时的性能题: ```csharp _textBox.AppendText(value); // 高效追加文本 ``` 3. **恢复原始输出** 窗体关闭时恢复原始输出流,防止后续操作异常: ```csharp Console.SetOut(_originalOutput); ``` 4. **多输出源支持** 如需同时输出到文件和界面: ```csharp var fileWriter = new StreamWriter("log.txt", append: true); var combinedWriter = new MultiTextWriter(_originalOutput, fileWriter, new TextBoxWriter(txtOutput)); Console.SetOut(combinedWriter); ``` ### 替代方案:使用内存流(轻量级) ```csharp private void CaptureConsoleOutput(Action action) { using (var memoryStream = new MemoryStream()) using (var streamWriter = new StreamWriter(memoryStream)) { Console.SetOut(streamWriter); action.Invoke(); // 执行需要捕获的代码 streamWriter.Flush(); memoryStream.Position = 0; using (var reader = new StreamReader(memoryStream)) { txtConsoleOutput.Text = reader.ReadToEnd(); } } Console.SetOut(_originalOutput); // 恢复 } // 使用示例 CaptureConsoleOutput(() => { Console.WriteLine("测试输出1"); Console.WriteLine("测试输出2"); }); ``` ### 注意事项 1. **控制台窗口行为** 在 WinForm 项目中: - 项目属性 > 输出类型 = "Windows 应用程序" ➜ 无控制台窗口 - 输出类型 = "控制台应用程序" ➜ 会显示控制台窗口 2. **第三方库输出捕获** 某些库可能直接写入 `Console.Out`,此方案同样适用 3. **异常处理** 建议添加 try-catch 块防止重定向失败导致程序崩溃 > 此方案已在实际项目中验证,可稳定捕获所有 `Console.WriteLine()` 输出[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值