1

我正在关注一个 Java 示例,该示例使用 Completion Service 向通过调用接收数据包的 3rd 方应用程序提交查询:

completionService.submit(new FetchData());

然后它调用:

Future<Data> future  = completionService.take();
Data data = future.get(timeout, TimeUnit.MILLISECONDS);

它等待提交的任务之一完成并返回数据。这两个调用在一个while(true)循环中。

我正在用 c# 开发一个应用程序,我想知道这是否是等待数据包的正确方法,以及我如何在 c# 中做到这一点。

我已经尝试过了,但我不确定我是否做得对:

new Thread(delegate() {
  Dictionary<ManualResetEvent, FetchData> dataDict = new Dictionary<ManualResetEvent, FetchData>();

  ManualResetEvent[] doneEvents;
  ManualResetEvent doneEvent;
  FetchData fetch;
  int index;

  while(true) {             
    // Create new fetch
    doneEvent = new ManualResetEvent(false);
    fetch = new FetchData(this, doneEvent);

    // event -> fetch association
    dataDict.Add(doneEvent, fetch);

    ThreadPool.QueueUserWorkItem(fetch.DoWork);

    doneEvents = new ManualResetEvent[dataDict.Count];
    dataDict.Keys.CopyTo(doneEvents, 0);

    // wait for any of them to finish
    index = WaitHandle.WaitAny(doneEvents, receiveThreadTimeout);

    // did we timeout?
    if (index == WaitHandle.WaitTimeout) {
      continue;
    }

    // grab done event
    doneEvent = doneEvents[index];
    // grab fetch
    fetch = dataDict[doneEvent];

    // remove from dict
    dataDict.Remove(doneEvent);

    // process data
    processData(fetch.GetData());               
  }

}).Start();

编辑:最后一点,我在使用 Mono 2.6 且仅限于 .NET 2.0 的 Unity 中使用它

编辑2:我改变了一些代码。我意识到 ThreadPool 有它自己的最大限制,如果没有剩余线程,它会将任务排队,所以我从我的代码中删除了该逻辑。

4

2 回答 2

0

事实证明,我只需要一个线程来监听数据包,因此我不必像上面的示例那样使用线程池。

于 2012-08-30T01:16:29.823 回答
0

您真的需要在 Unity3D 应用程序中使用多线程吗?我问这个是因为 Unity“不是”多线程的:有一种方法可以处理线程,但你最好依靠协程来做到这一点。请参阅此文档以了解有关协程的更多信息。

注意:如果您使用 Unity 3.5,它使用支持 .NET 4.0 几乎所有内容的 Mono 2.6.5。我不知道这个Task类,但它肯定涵盖了 .NET 3.0。

于 2012-08-29T21:02:53.833 回答