C#如何阻塞线程,直到另一个线程获得服务器响应

时间:2015-08-05 09:37:17

标签: c# multithreading asynchronous synchronous

我正在开发一个库,您可以在其中创建一个名称为

的服务器
UtilityServer server = new UtilityServer("TestServer1", 3500);

您还可以创建名称为

的客户端
UtilityClient client = new UtilityClient("TestClient1");

服务器使用您选择的端口在本地计算机上创建一个套接字。当服务器运行时,客户端可以通过以下方式连接:

client.Connect(ServerIP, 3500);

当我以事件为基础时,一切正常,例如:

client.UserNamesArrived += OnUserNamesArrived;
client.RequestUserNames();

private void OnUserNamesArrived(ReadOnlyCollection<string> userNames)
{
    // Do something with userNames
}

但是当我尝试在我的库中创建一个阻塞方法时,例如:

public ReadOnlyCollection<string> GetUserNames()
{
    // Request userNames from server
    // Wait until server sent us userNames
    // return userNames
}

// Running on seperate thread, gets messages that server sents to client
ReceiveMessages()
{
    while(_isConnected)
    {
    // Waits until message is received (_strReader.ReadLine())
    // Looks what message contains (Can also be other things then userNames)
    // Gets collection of userNames when message contains it (Working)
    // Triggers event 'UserNamesArrived' with userNames as argument
    }
}

我不知道如何。

现在我的问题是,我如何在GetUserNames-Thread中等待,直到我的ReceiveMessages-Thread获得userNames的集合,我该如何返回它们?

.Net-Framework中有类似的方法阻止线程,例如:

sqlCommand.ExecuteNonQuery();

这也会阻止它并等待响应,但是如何?

2 个答案:

答案 0 :(得分:1)

考虑System.Threading.WaitHandle的其中一个实现。

我经常使用AutoResetEvent来进行需要阻止的跨线程通知。

  

AutoResetEvent允许线程通过相互通信   信号。通常,在线程需要独占时使用此类   访问资源。

     

https://msdn.microsoft.com/en-us/library/system.threading.autoresetevent%28v=vs.110%29.aspx

由于信令性质,您经常会听到这种称为信号量的构造。 WaitHandles是一个操作系统功能,所以请确保正确处理手柄。

WaitHandle的重要特征是WaitOne方法。

  

WaitOneBlock当前线程,直到当前WaitHandle收到信号。

答案 1 :(得分:0)

您可以使用.NET框架的async和await属性。您需要将 ReceiveMessages()方法设置为异步任务,并使运行该方法的主线程 ReadOnlyCollection GetUserNames()等待 ReceiveMessages()完成......我认为它会起作用。

public async ReadOnlyCollection<string> GetUserNames()
{
// Request userNames from server
List<UserNames> userNameList = await ReceiveMessages();
// return userNames
}

// Running on seperate thread, gets messages that server sents to client
async Task<List<UserNames> ReceiveMessages()
{
// Looks what message contains
// Gets collection of userNames when requested (Working)
// Triggers event 'UserNamesArrived' with userNames as argument
}

看一下这个例子:await and async example