小编Jim*_*hel的帖子

异步引发事件

我正在研究在具有许多其事件订阅者的组件中进行异步事件调度的选项.在仔细阅读这些选项时,我遇到了这个例子:

public event ValueChangedEvent ValueChanged;
public void FireEventAsync(EventArgs e)
{
    Delegate[] delegates = ValueChanged.GetInvocationList();
    foreach (Delegate d in delegates)
    {
        ValueChangedEvent ev = (ValueChangedEvent)d;
        ev.BeginInvoke(e, null, null);
    }
}
Run Code Online (Sandbox Code Playgroud)

除了较旧的语法(示例来自.NET 1.1),我认为这是一个严重的资源泄漏.没有完成方法,没有轮询完成,或任何其他方式EndInvoke将被调用.

我的理解是每个人都BeginInvoke 必须有相应的EndInvoke.否则,有AsyncResult异常事件中引发的待处理对象实例以及异常事件期间引发的(可能)异常.

我意识到,通过提供回调和执行操作来改变它很容易EndInvoke,但如果我不需要...

处理异步延迟完全是另一回事,并且结合与UI线程同步的需要(即InvokeRequired等)可以很好地理解这些异步通知的整个想法.

那么,有两个问题:

  1. 我是否相信每BeginInvoke一个都需要相应的EndInvoke
  2. 除了我上面提到的,在Windows窗体应用程序中执行异步事件通知还有其他缺陷吗?

.net c# winforms

8
推荐指数
1
解决办法
9685
查看次数

TryFoo应该抛出异常吗?

.NET Framework中的一个常见模式是TryXXX模式(我不知道这是否是他们真正称之为的模式),其中被调用的方法尝试执行某些操作,True如果成功False则返回,或者操作失败.一个很好的例子是通用Dictionary.TryGetValue方法.

这些方法的文档说它们不会抛出异常:失败将在方法返回值中报告.到目前为止都很好.

我最近遇到了两种不同的情况,其中实现TryXXX模式的.NET Framework方法引发了异常.请参阅System.Random构造函数中的Bug?Uri.TryCreate抛出UriFormatException?详情.

在这两种情况下,该TryXXX方法都会调用其他方法来引发意外异常,并且这些异常会被转义.我的问题:这是否打破了不抛出异常的隐含合同?

换句话说,如果你正在写作TryFoo,你能保证异常无法逃脱,通过这样写吗?

public bool TryFoo(string param, out FooThing foo)
{
    try
    {
        // do whatever
        return true;
    }
    catch
    {
        foo = null;
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

这很诱人,因为这可以保证不会逃避任何例外,从而兑现隐含的合同.但这是一个隐藏的bug.

根据我的经验,我的直觉是,这是一个非常糟糕的主意.但是,如果TryFoo让一些异常逃脱,那么它真正说的是"我不会抛出任何我知道如何处理的异常",然后合同的整个想法"我不会抛出异常"被抛出窗口.

那么,你有什么看法?应该TryFoo处理所有异常,还是只处理它预期发生的异常?你的理由是什么?

.net exception

8
推荐指数
2
解决办法
689
查看次数

什么导致.NET Remoting中的"Tcp通道协议违反期待前导"?

我有一个分布式应用程序,它在内部千兆网络上使用.NET Remoting.有一台服务器,以及十几个连接到服务器的客户端.客户端运行多个线程,每个客户端最多可以有10个并发请求.

这个应用程序大多数时候都很好用.服务器一次保持数月.我不时会在客户端上遇到异常,我无法弄清楚导致异常的原因.异常和堆栈跟踪是:

System.Runtime.Remoting.RemotingException: Tcp channel protocol violation: expecting preamble.

Server stack trace: 
   at System.Runtime.Remoting.Channels.Tcp.TcpSocketHandler.ReadAndMatchPreamble()
   at System.Runtime.Remoting.Channels.Tcp.TcpSocketHandler.ReadVersionAndOperation(UInt16& operation)
   at System.Runtime.Remoting.Channels.Tcp.TcpClientSocketHandler.ReadHeaders()
   at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, ITransportHeaders& responseHeaders, Stream& responseStream)
   at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
Run Code Online (Sandbox Code Playgroud)

这是堆栈跟踪回到我进行远程调用的地方.

我看起来并且在我正在进行的调用中或在服务器返回的数据中找不到任何异常.

谷歌搜索此错误并不是很有成效.我见过的大多数错误都是围绕某人从HTTP转换为TCP而不是改变所有内容,所以当他们尝试连接时会遇到异常.在我的情况下,客户端将在我收到此错误之前运行几天.

另一个数据点:服务器确实收到了很多请求.大多数客户端都是Web爬虫,每个客户端每分钟向服务器发出2,000多个请求.因此,服务器每秒处理超过500个请求,具有更高流量的突发.在任何情况下,服务器似乎处理流量没问题,如果服务器过载,我会发现一个非常不同的错误.

是什么原因造成了这个错误?

.net remoting .net-remoting

8
推荐指数
1
解决办法
2万
查看次数

通过引用从C++/CLI传递给C#

似乎必须有一个重复的问题,但我一直无法找到它.

我正在写一个桥,让旧的C程序访问一些C#对象.该桥是用C++/CLI编写的.

在一种情况下,有一个C#函数定义为:

public static string GetNameAndValue(out int value);
Run Code Online (Sandbox Code Playgroud)

我的C++/CLI包装函数:

char* GetNameAndValue(int* value);
Run Code Online (Sandbox Code Playgroud)

这很容易从C调用.但是如何从C++/CLI调用C#方法?

我首先尝试了明显的:

String ^ str;
str = TheObject::GetNameAndValue(value);
Run Code Online (Sandbox Code Playgroud)

这给了我错误C2664:无法将参数2从'int*'转换为'int%'.

好的,那么,怎么样GetNameAndValue(%value)?这给了我错误C3071:运算符'%'只能应用于ref类的实例或值类型.

很公平.所以,如果我创建一个int我可以传递它%??

int foo;
str = TheObject::GetNameAndValue(%ix);
Run Code Online (Sandbox Code Playgroud)

没有骰子.C3071再次.我觉得奇怪,因为int肯定一种价值型.或者是吗?

必须有一些神奇的组合,%,^,和,或其他一些淫秽会做我想要的,但在这件事发誓30分钟后,我很难过.在Google上搜索C++/CLI和C#的不同组合,主要提供了有关如何从C#调用C++的信息.

所以,我的问题:你如何将intC++/CLI传递给期望out int(或者ref int,如果必须)的C#方法?

c# c++-cli

8
推荐指数
1
解决办法
5516
查看次数

配置Windows DNS解析程序缓存

请注意,我在谈论客户端DNS解析器缓存.此消息与Windows DNS服务器无关.

我有一个C#程序,可以执行很多DNS解析.因为HTTPWebRequest组件不允许我更改Host标头,所以我无法创建自己的内部DNS缓存.所以我必须依赖Windows DNS缓存,这似乎不适合更改.

有一篇相当不错的TechNet文章关于Windows Server 2003中的DNS缓存注册表设置,但我无法证明设置它们可以做任何事情.我通过Google搜索找到的所有其他页面都引用该页面,或者有时会错误地解释它.

Windows的ipconfig命令有一个/ displaydns开关,用于输出缓存的内容.据我所知,这是确定DNS缓存大小的唯一方法.在我使用2 GB内存的32位Windows XP盒子上进行的实验中,无论我将DNS缓存注册表值设置为什么,我总是在缓存中最终得到30到40个项目 - 即使在进行了数千次DNS解析之后.在具有16 GB内存的64位Windows 2008计算机上,我总是在缓存中获得270到300个项目.

我很难过.我不知道答案是什么,但我认为以下情况之一是这样的:

  1. 无法更改DNS解析程序缓存的大小.
  2. 这是可能的,但文档是错误的.
  3. 文档尽可能正确,但它不完整.
  4. 文档是正确和完整的,但我太愚蠢,无法理解它.
  5. 记录的注册表项实际上更改了缓存的大小,但ipconfig没有向我显示缓存中的所有条目.

有人能告诉我是否可以在Windows XP,Vista或Server 2008中配置DNS解析器缓存的大小?

.net c# dns

7
推荐指数
1
解决办法
8366
查看次数

在源代码中翻译注释和区域名称

有没有人知道批处理器或VS 2010插件/脚本可以让我将评论和地区名称从中文翻译成英文?

我发现的唯一一个处理所有字符串或一次只处理一个字符串.

我有两个很大的C#项目,我正在努力阅读.

谢谢.

c# translation localization visual-studio-2010

7
推荐指数
1
解决办法
916
查看次数

有没有更好的方法来组合这两个Linq表达式?

我有两个LINQ表达式,我认为我应该能够合并为一个.

我有一个推荐人列表,每个推荐人都参考了多个项目,我正在尝试确定最受欢迎的项目.每个推荐人向参考项目传达唯一的投票得分.也就是说,推荐人1可能会投票给0.2,推荐人2可能会投票给0.03.

简化Referrer课程:

class Referrer
{
    public double VoteScore { get; private set; }
    public List<int> Items { get; private set; }
    public Referrer(double v)
    {
        VoteScore = v;
        Items = new List<int>();
    }
}
Run Code Online (Sandbox Code Playgroud)

我的两个Linq表达式是:

var Votes =
    from r in Referrers
    from v in r.Items
    select new { ItemNo = v, Vote = r.VoteScore };
Run Code Online (Sandbox Code Playgroud)

这给了我一个清单:

ItemNo:1, Vote:0.2
ItemNo:3, Vote:0.2
ItemNo:1, Vote:0.03
Run Code Online (Sandbox Code Playgroud)

现在,我可以用我的第二个表达式进行分组,求和和排序:

var SortedByScore = 
    from v in Votes
    group v by v.ItemNo into g …
Run Code Online (Sandbox Code Playgroud)

c# linq

6
推荐指数
1
解决办法
247
查看次数

这个字符串操作代码的空间复杂性是多少?

这段代码来自Cracking the Coding访谈书.

public static boolean isUniqueChars2(String str) {
    boolean[] char_set = new boolean[256];
    for (int i = 0; i < str.length(); i++) {
        int val = str.charAt(i);
        if (char_set[val]) return false;
        char_set[val] = true;
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

作者提到,

时间复杂度为O(n),其中n是字符串的长度,空间复杂度为O(n).

我理解时间复杂度为O(n)但我不明白空间复杂度怎么可能是O(n)

我的想法:无论输入(str)大小是多少,char_set都将保持256大小的数组.即使"str"的长度为100,000,char_set仍然是256个元素的数组.所以我想,因为这个函数的内存需求不随输入的大小而变化并保持常数256,所以空间复杂度是常数,即O(1).

有人可以解释,如果我错了(为什么?)

非常感谢.

string algorithm complexity-theory

6
推荐指数
1
解决办法
1520
查看次数

WIF滑动会话重新进行身份验证

我在依赖方应用程序中实现了滑动会话,如WIF 4.5的滑动会话中所述.尽管这样做很有效,但是有一个问题似乎没有人谈论过.

正如链接的博客文章指出的那样,当RP令牌到期时,下次发出请求时,将从STS重新发出令牌.当然,假设STS会话的生命周期比RP的会话生存期长,如果你正在实现滑动会话,几乎可以肯定.

无论如何,这完全打败了滑动会话的全部要点.

似乎没有人在谈论RP会话到期时该怎么做.我想要的是,如果RP会话超时(通常是因为有人离开他的桌子10分钟),我的应用程序是否会重定向到用户可以重新进行身份验证的STS登录页面,然后被重定向回我要求的页面; 或者也许是我提出请求时我所在的页面.

我几乎可以肯定这是可能的,但我完全不知道它是如何完成的.

这是我在global.asax中的代码:

    private const int InactivityTimeout = 5; // minutes

    void SessionAuthenticationModule_SessionSecurityTokenReceived
        (object sender, SessionSecurityTokenReceivedEventArgs e)
    {
        var now = DateTime.UtcNow;
        var validFrom = e.SessionToken.ValidFrom;
        var validTo = e.SessionToken.ValidTo;
        double halfSpan = (validTo - validFrom).TotalMinutes/2;
        if (validFrom.AddMinutes(halfSpan) < now && now < validTo)
        {
            // add more time
            var sam = sender as SessionAuthenticationModule;

            e.SessionToken = sam.CreateSessionSecurityToken(
                e.SessionToken.ClaimsPrincipal,
                e.SessionToken.Context,
                now,
                now.AddMinutes(InactivityTimeout),
                e.SessionToken.IsPersistent);
            e.ReissueCookie = true;
        }
        else
        {
            // re-authenticate …
Run Code Online (Sandbox Code Playgroud)

authentication wif thinktecture-ident-server

6
推荐指数
1
解决办法
2914
查看次数

Windows API中提供了哪些定期计时器对象?

在研究用于获取比.NET定时器对象提供的15毫秒的分辨率更好(见选项/sf/ask/262082271/)我正在查看Windows提供的不同计时器对象.我发现了以下内容:

Windows API中是否还有其他计时器类型?

winapi timer

5
推荐指数
1
解决办法
3504
查看次数