我在返回在其他线程中创建的对象时遇到问题。 情况就是这样,我的应用程序需要向远程服务器发送一些请求并等待回答。 在主线程(1)中,我有一个名为SendAndWait的方法。此方法将消息放入消息队列中以便发送并等待答案。 另一个线程(2)发送队列中的消息。 第三个线程(3)接收消息并将消息及其答案返回主线程(1)。
这是我的代码。
线程1:
void SendAndWait()
{
AutoResetEvent waitForAnswer = new AutoResetEvent(false);
int msgReferenceNumber = 1;
MyMessage msg;
// Register to wait for answer to the message with the number = msgReferenceNumber
RegisterToWait(msgNumber, waitForAnswer, ref msg);
// Send the request to the server, with the reference number.
SendRequest(msgReferenceNumber);
// Wait until the server send my answer
waitForAnswer.WaitOne();
// Now I have my answer. BUT I HAVE msg == null
MessageBox.Show(msg.Text);
}
主题2:
public class WhoWait
{
public int RefNumMsg;
public AutoResetEvent WaitForAnswer;
public MyMessage MessageWithAnswer;
}
// In this Dicctionary I save who wait for answers.
private Dictionary<int, WhoWait> Waiting = new Dictionary<WhoWait>();
void RegisterToWait(int msgRefNumber, AutoResetEvent waitForAnswer, ref msgWithAnswer)
{
WhoWait w = new WhoWait();
w.RefNumMsg = msgRefNumber;
w.WaitForAnswer = waitForAnswer;
w.MessageWithAnswer = msgWithAnswer;
Waiting.Add(msgRefNumber, w);
}
Thread3:
void OnRecieve()
{
// Get data from server
MyMessage msg = GetMessageData();
// Search for someone waiting for this answer
WhoWait w = Wainting[msg.RefNum];
// Set the response message
w.MessageWithAnswer = msg;
// Warn to the main thread. Message with their answer arrive
w.WaitForAnswer.Set();
}
除了Message引用之外,整个过程都在工作。 当我读取对象时,我传递了ref键,我有一个空值。
有人可以帮助我吗?
提前致谢。
答案 0 :(得分:3)
使用ref传递参数时,可以在函数中设置对象引用。当你像这样使用它时:
w.MessageWithAnswer = msgWithAnswer;
它没有使w.MessageWithAnswer成为引用的副本 - 它将w.MessageWithAnswer设置为msgWithAnswer当前所指的任何内容。分配MessageWithAnswer时,它不会更改msgWithAnswer。
答案 1 :(得分:2)
我解决这个问题,添加一个保留对象的类(OneMessageIn类)。
// This class keep the copy of the message when arrived
public class OneMessageIn
{
public MyMessage Message
}
void SendAndWait()
{
AutoResetEvent waitForAnswer = new AutoResetEvent(false);
int msgReferenceNumber = 1;
OneMenssageIn msgBox = new OneMessageIn();
// Register to wait for answer to the message with the number = msgReferenceNumber
RegisterToWait(msgNumber, waitForAnswer, ref msgBox);
// Send the request to the server, with the reference number.
SendRequest(msgReferenceNumber);
// Wait until the server send my answer
waitForAnswer.WaitOne();
// Now I have my answer!!!
MessageBox.Show(msgBox.Message.Text);
}
public class WhoWait
{
public int RefNumMsg;
public AutoResetEvent WaitForAnswer;
public OneMessageIn MessageWithAnswer;
}
// In this Dicctionary I save who wait for answers.
private Dictionary<int, WhoWait> Waiting = new Dictionary<WhoWait>();
// I'm not sure if ref is necesary, but with it works. I don't try without ref.
void RegisterToWait(int msgRefNumber, AutoResetEvent waitForAnswer, ref OneMessageIn msgBox)
{
WhoWait w = new WhoWait();
w.RefNumMsg = msgRefNumber;
w.WaitForAnswer = waitForAnswer;
w.MessageWithAnswer = msgBox;
Waiting.Add(msgRefNumber, w);
}
void OnRecieve()
{
// Get data from server
MyMessage msg = GetMessageData();
// Search for someone waiting for this answer
WhoWait w = Wainting[msg.RefNum];
// Set the response message
w.MessageWithAnswer.Message = msg;
// Warn to the main thread. Message with their answer arrive
w.WaitForAnswer.Set();
}
这个解决方案对我很有用。
感谢所有帮助我解决这个问题的人。
答案 2 :(得分:1)
您没有给msgWithAnswer
一个值,您传递空引用然后不为空引用赋值。
void RegisterToWait(int msgRefNumber, AutoResetEvent waitForAnswer, ref msgWithAnswer)
{
// msgWithAnswer = something here
WhoWait w = new WhoWait();
w.RefNumMsg = msgRefNumber;
w.WaitForAnswer = waitForAnswer;
w.MessageWithAnswer = msgWithAnswer;
Waiting.Add(msgRefNumber, w);
}
答案 3 :(得分:1)
我使用Action
个对象而不是引用,因为(如前所述)你不能像你想要的那样使用ref
。见下文:
void SendAndWait()
{
AutoResetEvent waitForAnswer = new AutoResetEvent(false);
int msgReferenceNumber = 1;
MyMessage msg;
// Register to wait for answer to the message with the number = msgReferenceNumber
RegisterToWait(msgNumber, waitForAnswer, receivedMessage => msg = receivedMessage);
// Send the request to the server, with the reference number.
SendRequest(msgReferenceNumber);
// Wait until the server send my answer
waitForAnswer.WaitOne();
// Now I have my answer. BUT I HAVE msg == null
MessageBox.Show(msg.Text);
}
public class WhoWait
{
public int RefNumMsg;
public AutoResetEvent WaitForAnswer;
public Action<MyMessage> MessageSetter;
}
void RegisterToWait(int msgRefNumber, AutoResetEvent waitForAnswer, Action<MyMessage> msgSetter)
{
WhoWait w = new WhoWait();
w.RefNumMsg = msgRefNumber;
w.WaitForAnswer = waitForAnswer;
w.MessageSetter = msgSetter;
Waiting.Add(msgRefNumber, w);
}
void OnRecieve()
{
// Get data from server
MyMessage msg = GetMessageData();
// Search for someone waiting for this answer
WhoWait w = Wainting[msg.RefNum];
// Set the response message
w.MessageSetter(msg);
// Warn to the main thread. Message with their answer arrive
w.WaitForAnswer.Set();
}