gpt4 book ai didi

c# - 从服务总线队列接收消息适用于控制台应用程序,但不适用于 Windows 窗体应用程序?

转载 作者:行者123 更新时间:2023-12-03 02:16:36 27 4
gpt4 key购买 nike

我有以下 C# 函数,允许我从 Azure 接收来自给定队列的消息,它在控制台应用程序上运行良好:

public  async Task MainReceiver()
{
queueClient = new QueueClient(connectionString, queueName);

var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler)
{
MaxConcurrentCalls = 5,
AutoComplete = false,

};

queueClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions);

Console.ReadLine();

await queueClient.CloseAsync();
}

public async Task ProcessMessagesAsync(Message message, CancellationToken token)
{
var jsonString = Encoding.UTF8.GetString(message.Body);
Console.WriteLine($"Person Received: { jsonString }");
List<string> data = new List<string>();

if (messageLists.ContainsKey(queueName))
{
data = messageLists[queueName];
messageLists.Remove(queueName);
data.Add(jsonString);
}
else
{
data.Add(jsonString);
}
messageLists.Add(queueName, data);

await queueClient.CompleteAsync(message.SystemProperties.LockToken);
}

我现在的目标是使用列表框控件列出消息。但是,如果我尝试在单击按钮时调用相同的主要方法,则什么也不会发生,在 Debug模式下,我注意到我的 win 表单应用程序永远不会到达 ProcessMessagesAsync 中的断点。

public async void button2_Click(object sender, EventArgs e)
{
await receiveMessage();
}
public async Task receiveMessage()
{
await messages.MainReceiver();
List<string> data = new List<string>();
data = messages.messageLists["eventsqueue"];
for (int i = 0; i < messages.messageLists.Count; i++)
listBox1.Items.Add(data[i]);
}

我尝试使用以下代码在线程池中对我的任务进行排队,但没有帮助:

ThreadPool.QueueUserWorkItem(async (w) => await messages.MainReceiver());

最佳答案

请按照以下解决方法将服务总线队列消息放入Windows 窗体

将数据显示到 LISTBOX 的三个主要步骤

  1. 使用 ListBox 类提供的 ListBox() 构造函数创建列表框。

     ListBox listBox1 = new ListBox();
  2. 设置/添加 ListBox 类提供的 ListBox 的 Items 属性。

     listBox1.Items.Add("your data to add in listbox");
  3. 使用 Add() 方法将此 ListBox 控件添加到表单。

     this.Controls.Add(listBox1);

这里我按照上述步骤操作。

Program.cs

    using System.Collections.Generic;
using System.Windows.Forms;

namespace servicebuswinform
{
using Microsoft.Azure.ServiceBus;
using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
const string ServiceBusConnectionString = <ServiceBus Connection string>;
const string QueueName = "<Queue name>";
static IQueueClient queueClient;
public static List<string> data = new List<string>();

[STAThread]

public static void Main()
{
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}

public static async Task MainAsync()
{
const int numberOfMessages = 10;
queueClient = new QueueClient(ServiceBusConnectionString, QueueName);
RegisterOnMessageHandlerAndReceiveMessages();
// Send Messages
await SendMessagesAsync(numberOfMessages);
await queueClient.CloseAsync();
}

public static void RegisterOnMessageHandlerAndReceiveMessages()
{
var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler)
{
MaxConcurrentCalls = 1,
AutoComplete = false
};
// Register the function that will process messages
queueClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions);
}

public static async Task ProcessMessagesAsync(Message message, CancellationToken token)
{
//Adding message into list
data.Add("Received message: SequenceNumber:"+ message.SystemProperties.SequenceNumber.ToString()+" Body:" + Encoding.UTF8.GetString(message.Body));
await queueClient.CompleteAsync(message.SystemProperties.LockToken);
}

// Use this Handler to look at the exceptions received on the MessagePump

public static Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs)
{
Console.WriteLine($"Message handler encountered an exception {exceptionReceivedEventArgs.Exception}.");
var context = exceptionReceivedEventArgs.ExceptionReceivedContext;
Console.WriteLine("Exception context for troubleshooting:");
Console.WriteLine($"- Endpoint: {context.Endpoint}");
Console.WriteLine($"- Entity Path: {context.EntityPath}");
Console.WriteLine($"- Executing Action: {context.Action}");
return Task.CompletedTask;
}

public static async Task SendMessagesAsync(int numberOfMessagesToSend)
{
try
{
for (var i = 0; i < numberOfMessagesToSend; i++)
{
// Create a new message to send to the queue
string messageBody = $"Message {i}";
var message = new Message(Encoding.UTF8.GetBytes(messageBody));
// Write the body of the message to the console
Console.WriteLine($"Sending message: {messageBody}");
// Send the message to the queue
await queueClient.SendAsync(message);
}
}
catch (Exception exception)
{
Console.WriteLine($"{DateTime.Now} :: Exception: {exception.Message}");
}
}
}
}

Form.cs

这里我添加一个按钮,如果我们点击该按钮,它将获取服务总线队列消息并将其添加到列表框中。

    using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace servicebuswinform
{
public partial class Form1 : Form
{
public static List<string> data1 = new List<string>();
public Form1()
{
InitializeComponent();
}

public async void button1_Click(object sender, EventArgs e)
{
await receiveMessage();
ListBox listBox1 = new ListBox();
this.listBox1.Visible = true;
for (int i = 0; i < data1.Count; i++)
{
listBox1.FormattingEnabled = true;
listBox1.Enabled = true;
listBox1.Size = new System.Drawing.Size(692, 214);
listBox1.Location = new System.Drawing.Point(1, 131);
listBox1.MultiColumn = true;
listBox1.SelectionMode = SelectionMode.MultiExtended;
listBox1.BeginUpdate();
listBox1.Items.Add("item" + data1[i].ToString());
}
this.Controls.Add(listBox1);
}

public static async Task receiveMessage()
{
await Program.MainAsync();
data1 = Program.data;
}
private void Form1_Load(object sender, EventArgs e)
{
this.listBox1.Visible = false;
}
}
}

您可以按照我提到的上述步骤进行操作。使用这个我可以看到 Windows 窗体中的服务总线队列消息列表

enter image description here

关于c# - 从服务总线队列接收消息适用于控制台应用程序,但不适用于 Windows 窗体应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71002520/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com