Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在BeginXXX和EndXXX方法中使用AsyncWaitHandle_C#_Asynchronous_Dns - Fatal编程技术网

C# 在BeginXXX和EndXXX方法中使用AsyncWaitHandle

C# 在BeginXXX和EndXXX方法中使用AsyncWaitHandle,c#,asynchronous,dns,C#,Asynchronous,Dns,我想调用一个异步操作,该操作返回一个IAsyncResult对象,特别是System.Net.Dns类的GetHostEntry方法 我知道我应该调用IAsyncResult的AsyncWaitHandle属性的WaitOne方法,等待操作完成,但显然我错了,因为这段代码不起作用: using System; using System.Net; static class Program { class GetHostEntryState { public IPHost

我想调用一个异步操作,该操作返回一个
IAsyncResult
对象,特别是
System.Net.Dns
类的
GetHostEntry
方法

我知道我应该调用
IAsyncResult
AsyncWaitHandle
属性的
WaitOne
方法,等待操作完成,但显然我错了,因为这段代码不起作用:

using System;
using System.Net;

static class Program {

    class GetHostEntryState {
        public IPHostEntry Value {
            get;
            set;
        }
    }

    static void Main(string[] args) {
        string hostName = "somehost";
        int timeout = 1000;

        var state = new GetHostEntryState();
        var asyncResult = Dns.BeginGetHostEntry(hostName, ar => {
            ((GetHostEntryState)ar.AsyncState).Value = Dns.EndGetHostEntry(ar);
        }, state);
        if (asyncResult.AsyncWaitHandle.WaitOne(timeout) && asyncResult.IsCompleted) {
            if (state.Value == null) {
                // we always hit this condition
                Console.WriteLine("state.Value == null");
                return;
            }
            foreach (var address in state.Value.AddressList) {
                Console.WriteLine(address);
            }
        } else {
            Console.WriteLine("timed out");
        }
    }
}

使用
ManualResetEvent
对象执行同步。有必要吗?如果是这样,那么这里的
AsyncWaitHandle
属性有什么用?

因为我想要的是一个带有超时的GetHostEntry,所以我提出了这个解决方案,如果我理解正确的话,应该可以避免资源泄漏,因为最终还是会调用EndGetHostEntry操作

我在这里分享它,以防它对其他人有用:)


从你所看到的,你可以看出这是必要的。在线程竞争中,AsyncWaitHandle.WaitOne()通常在回调之前完成。通过调用异步方法但同步等待它,您陷入了这个困境。可能是因为你想要暂停。下一件你必须担心的事情是,当你有一个超时时间时,你是如何清理的。@HansPassant:那么AsyncWaitHandle.WaitOne()的用途是什么呢?我仍然不明白…它的目的是告诉您何时可以调用EndXxx()方法而不阻塞它。如果没有回调,则在WaitOne()调用后调用EndGetHostEntry(),这将起作用。但是因为超时,你付不起。不打电话会导致资源泄漏。@HansPassant:谢谢,我想我现在知道了。
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

public sealed class HostEntryTimeout {

    public IPHostEntry HostEntry {
        get;
        private set;
    }

    string _hostName;
    int _timeoutInMilliseconds;
    ManualResetEvent _getHostEntryFinished;

    public HostEntryTimeout(string alias, int timeoutInMilliseconds) {
        _hostName = alias;
        _timeoutInMilliseconds = timeoutInMilliseconds;
        _getHostEntryFinished = new ManualResetEvent(false);
    }

    /// <summary>
    /// Gets the IPHostEntry.
    /// </summary>
    /// <returns>True if successful, false otherwise.</returns>
    public bool GetHostEntry() {
        _getHostEntryFinished.Reset();
        Dns.BeginGetHostEntry(_hostName, GetHostEntryCallback, null);
        if (!_getHostEntryFinished.WaitOne(_timeoutInMilliseconds)) {
            return false;
        }
        if (HostEntry == null) {
            return false;
        }
        return true;
    }

    void GetHostEntryCallback(IAsyncResult asyncResult) {
        try {
            HostEntry = Dns.EndGetHostEntry(asyncResult);
        } catch (SocketException) {
        }
        _getHostEntryFinished.Set();
    }
}
var hostEntryTimeout = new HostEntryTimeout("somehost", 1000);
if (hostEntryTimeout.GetHostEntry()) {
    // success, do something with the hostEntryTimeout.HostEntry object
}