#c# #c #msmq
#c# #c #msmq
Вопрос:
Я хочу записывать сообщения в очередь MSMQ с помощью C и читать их с помощью C #. Я отправляю сообщения в виде строк. Это работает нормально, если я одновременно пишу и читаю сообщения на C , но если я пытаюсь прочитать сообщение с помощью C #, я получаю только первый символ сообщения. (например: я отправляю «abcd», а получаю только «a»).
Я также должен упомянуть, что я использую этот код в Windows Mobile.
Вот код c :
HRESULT MSMQManager::WriteMessage(LPWSTR text){
// define the required constants and variables.
const int NUMBEROFPROPERTIES = 5; // number of properties
DWORD cPropId = 0; // property counter
HRESULT hr = MQ_OK; // return code
HANDLE hQueue = NULL; // queue handle
// define an MQMSGPROPS structure.
MQMSGPROPS msgProps;
MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
HRESULT aMsgStatus[NUMBEROFPROPERTIES];
// message label
aMsgPropId[cPropId] = PROPID_M_LABEL;
aMsgPropVar[cPropId].vt = VT_LPWSTR;
aMsgPropVar[cPropId].pwszVal = L"msg";
cPropId ;
// message body
aMsgPropId[cPropId] = PROPID_M_BODY;
aMsgPropVar[cPropId].vt = VT_VECTOR | VT_UI1;
aMsgPropVar[cPropId].caub.pElems = (LPBYTE)text;
aMsgPropVar[cPropId].caub.cElems = wcslen(text)*2;
cPropId ;
// message body type
aMsgPropId[cPropId] = PROPID_M_BODY_TYPE;
aMsgPropVar[cPropId].vt = VT_UI4;
aMsgPropVar[cPropId].ulVal = VT_LPWSTR;
cPropId ;
// initialize the MQMSGPROPS structure.
msgProps.cProp = cPropId;
msgProps.aPropID = aMsgPropId;
msgProps.aPropVar = aMsgPropVar;
msgProps.aStatus = aMsgStatus;
// Call MQSendMessage to send the message to the queue.
hr = MQSendMessage(
this->writeHandle, // Queue handle
amp;msgProps, // Message property structure
MQ_NO_TRANSACTION // Not in a transaction
);
Вот код c #:
public string ReadMessageUnformatted()
{
try
{
Message received;
Stream bodyStream = null;
StreamReader sr = null;
char[] buffer = new char[256];
received = this.readMQ.Receive();
bodyStream = received.BodyStream;
sr = new StreamReader(bodyStream);
//this.lastReceived = sr.ReadLine();
sr.Read(buffer, 0, 256);
this.lastReceived = new string(buffer);
return lastReceived;
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString(), "Exception");
return null;
}
}
Я использую BodyStream вместо Body для сообщения, потому что я не хочу использовать какой-либо форматировщик сообщений.
Спасибо
Комментарии:
1. Работает ли это с
string text = sr.ReadToEnd()
?2. Нет, это не работает ни с ReadToEnd(). Таким образом, приложение блокируется в ожидании окончания потока. Как вы думаете, это может быть проблемой, потому что я установил тело сообщения в качестве указателя?
3. Посмотрите мой ответ, может быть, что-то есть.
Ответ №1:
Я сам решил проблему. Я опубликую здесь код, возможно, кому-то еще интересно.
try
{
Message received;
Stream bodyStream = null;
int bufLength = 512;
byte[] buffer = new byte[bufLength];
received = this.readMQ.Receive();
bodyStream = received.BodyStream;
bodyStream.Read(buffer, 0, bufLength);
this.lastReceived = Encoding.Unicode.GetString(buffer, 0, buffer.Length);
return lastReceived;
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString(), "Exception");
return null;
}
Комментарии:
1. Огромный 1. Только что сам столкнулся с этой проблемой. Спас положение!
Ответ №2:
Может быть, вы можете попробовать:
aMsgPropVar[cPropId].ulVal = VT_BSTR;
VT_BSTR используется для обозначения строки в юникоде.
VT_LPWSTR должен завершаться нулем, чего, я думаю, в вашей строке нет.
Комментарии:
1. Я решил проблему, прочитав байты вместо символов, а затем преобразовал массив байтов в строку. Спасибо за помощь и интерес.