小编Jor*_*rdy的帖子

是不是一味地使用InvokeRequired只是不好的做法?

我是一名新手程序员,所以我可能在这里完全弄错了,但是这个问题让我更加困惑.

这实际上是这个问题的后续行动.

接受的答案是,你必须调用InvokeRequired以避免一些开销,因为你有可能已经在UI线程上运行了.

理论上,我同意它可以节省一些时间.经过一些测试后,我发现使用Invoke所需的时间比正常调用操作大两倍(测试如设置标签文本n次,或在RichTextBox中放置一个非常非常大的字符串).

但!然后有练习.

MSDN文档说:

此属性可用于确定是否必须调用invoke方法,如果您不知道哪个线程拥有控件,这可能很有用.

在大多数情况下,您确实知道何时尝试从另一个线程访问控件.实际上,我能想到的唯一情况是,从一个可以被线程X调用的方法以及所有者线程访问控件时.对我来说这是一个非常不可能的情况.

即使你真的不知道哪个线程试图操纵控件,也有一个事实是UI线程不必经常更新.对于您的GUI,25-30 fps之间的任何内容都应该没问题.并且在UI控件中进行的大多数更改所花费的时间远远少于毫秒.

因此,如果我理解正确,那么您必须检查是否需要调用的唯一情况是您何时不知道哪个线程正在访问控件以及何时GUI更新需要超过40毫秒才能完成.

然后我在http://programmers.stackexchange.com上询问了这个问题的答案.这表明,当您不需要它时,您不应该忙于过早优化.特别是如果它牺牲了代码的可读性.

所以这让我想到了一个问题:当你知道一个不同的线程访问一个控件时,你不应该只使用invoke,只有当你知道你的UI线程可以访问那段代码并且你发现它应该运行得更快时,你才应检查是否需要调用?

PS:在校对我的问题后,听起来真的像我在咆哮.但实际上我只是好奇为什么InvokeRequired似乎被许多比我更有经验的程序员所滥用.

c# multithreading invoke invokerequired

21
推荐指数
2
解决办法
1129
查看次数

为什么bool.TrueString和bool.FalseString存在?

我正在阅读布尔结构的MSDN文章,当我看到一个布尔有两个字段:TrueStringFalseString.这些分别返回"真"和"假".

经过一些搜索,我能找到的唯一例子就是这篇dotnetperls文章.文章指出:

程序通常需要这些字符串.TrueString和FalseString是一对有用的只读成员.它们以字符串格式表示真值.它们直接使用字符串文字提供间接和抽象.

所以看起来它对某些情况很有用.但同一篇文章未能提供一个现实的例子(无论如何都是恕我直言).

一些进一步的阅读也引起了我的注意:TrueString和FalseString是公共静态只读字段.而这dornetperls文章指出:

语言规范建议使用公共静态只读字段...当字段将来可能发生变化时.

现在我对此有所了解.如果.NET开发人员决定分别将"True"和"False"更改为"OkeyDokey"和"Negatory",那么使用TrueString和FalseString是明智的.

但这仍然留给我一个问题:在什么样的场景中你想比较字符串和布尔值的字符串文字?因为看起来很普遍:"程序经常需要"它们.

c# boolean string-literals

11
推荐指数
1
解决办法
4926
查看次数

Thread.Sleep(0)不能像描述的那样工作?

我目前正在阅读这篇关于线程的优秀文章,并阅读以下文字:

Thread.Sleep(0)立即放弃线程的当前时间片,自愿将CPU交给其他线程.

我想测试这个,下面是我的测试代码:

static string s = "";

static void Main(string[] args)
{
    //Create two threads that append string s
    Thread threadPoints = new Thread(SetPoints);
    Thread threadNewLines = new Thread(SetNewLines);

    //Start threads
    threadPoints.Start();
    threadNewLines.Start();

    //Wait one second for threads to manipulate string s
    Thread.Sleep(1000);

    //Threads have an infinite loop so we have to close them forcefully. 
    threadPoints.Abort();
    threadNewLines.Abort();

    //Print string s and wait for user-input
    Console.WriteLine(s);
    Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)

threadPoints和threadNewLines运行的函数:

static void SetPoints()
{
    while(true)
    {
        s …
Run Code Online (Sandbox Code Playgroud)

c# thread-sleep

10
推荐指数
1
解决办法
799
查看次数

如何截断字符串以适应容器?

有很多的问题(比如:1,2,3,4,5),询问如何可以截断字符串的字符所需量.但我希望将一段文本截断以容纳在容器中.(IE:按字母宽度(以像素为单位)裁剪字符串,而不是字符.

如果你使用WPF这很容易,但在WinForms中却没有那么多......

那么:如何截断字符串以使其适合容器?

c# truncate winforms

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

Visual Studio在调试时显示错误的值?

当我看到奇怪的东西时,我正在调试我的代码.基本上它归结为:

怪事

你在这里看到的是一个带有负值的unsigned int ...

我还注意到一些周围的变量没有value pop-up(?)而其他变量没有.但是这个变量是唯一一个具有不可能价值的变量.

这怎么可能?

我只有C#Visual Studio 2010,所以我不知道其他版本或不同语言存在此问题.如果是这种情况,我会相应地更改标题和标签.

c# debugging visual-studio

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

Moby Dick的例外情况

有多种问题(1,2,3,4等等等等)被称为"为什么不是这个异常捕获".可悲的是,这些解决方案都不适合我......所以我遇到了一个真正无法捕获的异常.

我有一段代码(.NET 4.0)检查大文本文件的数字和数字.测试时我遇到了运行时异常:

例外

你在这里看到的是一个带有ArgumentOutOfRangeException的catchblock的try-catch模式.但是在运行时,try块会抛出一个未被捕获的ArgumentOutOfRangeException.

我阅读了关于try-catch结构的C#语言规范部分,它说:

如果可以访问try语句,则可以访问try语句的catch块.

所以理论上上面的代码应该捕获异常.

然后我认为它可能与这个代码在任务中运行这一事实有关(在处理文本文件期间我也想更新UI,所以我做异步).我周围中搜索,然后我找到这个答案由乔恩斯基特.基本上建议我在try-catch块中使用Task.Wait来捕获任何异常.

我现在面临的问题是我无法真正调用Task.Wait,因为这会阻塞作为我的UI线程的调用线程!然后我想我可以创建一个额外的任务层来等待该任务:

//Code called from the UI
System.Threading.Tasks.Task.Factory.StartNew(()=>
{
    //Create a new task and use this task to catch any exceptions
    System.Threading.Tasks.Task task = System.Threading.Tasks.Task.Factory.StartNew(MethodWithException);
    try
    {
        task.Wait();
    }
    catch(Exception)
    {
        MessageBox.Show("Caught it!");
    }
});
Run Code Online (Sandbox Code Playgroud)

但是这仍然会产生相同的结果......然后我认为这可能是因为我对Exceptiontype不够具体.但C#语言规范指出:

某些编程语言可能支持不能表示为从System.Exception派生的对象的异常,尽管C#代码永远不会生成此类异常.

因此,除非您使用一些粗略的第三方API,否则在使用时总是很好Exception.所以我发现自己有一个Jon Skeet的建议答案,这对我来说并不适用.就在那时,我知道我应该停止尝试......

那么有谁知道发生了什么?我该如何解决这个问题?我知道我可以检查是否i等于或大于text.Length但是理解发生的事情比工作代码更重要.

c# exception .net-4.0

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

使抽象类不可见; 或者:隐藏我的BananaHuman

背景:我仍然是C#新手,这是我的第一个继承的大项目.以下故事是我目前情况的简化示例:

假设我有一个叫做的课程LivingOrganism.每个生物都可以使用这个类作为基础并继承所有生物体共有的功能.

当我在其中一些derived课程上工作时,我发现香蕉和人类非常相似.虽然它没有多大意义,它们看起来没什么相似之处,但它们显然具有大多数共同的"功能".

代码重复很糟糕,所以我写了一个新类来降低维护成本.这个类叫做:BananaHuman.我的Human班级和Banana班级继承自BananaHuman.


问题:

我对我的BananaHuman没有任何问题(即我明白它意味着什么以及它存在的原因).但最终,其他人(即使那些没有(完全)理解继承的人)也必须使用我的LivingCreatures.dll.并且他们不明白为什么intellisense会在他们输入'B'时建议BananaHuman.

并考虑以下代码:

//Valid and makes sense.
foreach(LivingOrganism foo in cityOfNeyYork) { /*embedded statement*/ }
Run Code Online (Sandbox Code Playgroud)

但是想象一下,如何怪异/混乱,如果我们代替它看起来Living OrganismBananaHuman.

我无法制作BananaHuman private,protected或者protected internal(在命名空间中定义的元素不能以这种方式显式声明).我也做不到internal,因为Human而且Banana 必须如此public.如果我试试这个,我会收到一条错误消息,说明存在inconsistent accessibility问题.

我觉得我错过了明显的,但我能做什么/应该做什么?我留下了几个选项/问题:

  1. 是否有可能"隐藏" BananaHuman以避免混淆?
  2. 我应该重写BananaHuman一些非常长的技术,比如DnaRelatedOrganismsType[X]"X"描述它们的独特关系吗?
  3. 如果我只是删除BananaHuman,让HumanBanana …

c# inheritance abstract-class

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

确定是谁解雇了一个事件

背景:

在我的winforms表单中,我有一个Checked ListView和一个名为checkBoxAll的"master"复选框.主人的行为如下:

  • 如果选中或取消选中主服务器,则所有ListViewItems必须相应地更改.

  • 如果用户取消选中ListViewItem,则主服务器必须相应地更改.

  • 如果用户检查了ListViewItem,并且还检查了所有其他ListViewItem,则主服务器必须相应地进行更改.

我编写了以下代码来模仿这种行为:

private bool byProgram = false; //Flag to determine the caller of the code. True for program, false for user.

private void checkBoxAll_CheckedChanged(object sender, EventArgs e)
{
    //Check if the user raised this event.
     if (!byProgram)
     {
         //Event was raised by user!

         //If checkBoxAll is checked, all listviewitems must be checked too and vice versa.

         //Check if there are any items to (un)check.
         if (myListView.Items.Count > 0)
         {
             byProgram = …
Run Code Online (Sandbox Code Playgroud)

c# events

5
推荐指数
2
解决办法
1863
查看次数

.NET GarbageCollector真的是GarbageCollector吗?

我正在开发一个实现IDisposable接口的项目.在这个项目中,我发现我对GarbageCollector的了解最好.所以我开始阅读一些文档,最后我在MSDN上找到了"垃圾收集基础"一文.

你必须明白,在这一点上,我一直认为GarbageCollector是在下水道工作的人,他清理了来自该计划的废物.因此,我很惊讶地阅读以下片段:

垃圾回收器由CLR初始化后,它会分配一段内存来存储和管理对象.

一段后来,该文件指出:

为了保留内存,垃圾收集器调用Win32 VirtualAlloc函数,并为托管应用程序一次保留一段内存.垃圾收集器还根据需要保留段,并通过调用Win32 VirtualFree函数将段释放回操作系统(在清除任何对象之后).

如果我理解正确,GarbageCollector实际上是.NET程序的MemoryManager!

我知道,它仍然收集垃圾.但这不就像把歌手称为麦克风持有人吗?当然,这是真的,但几乎不是你付钱看他们的原因.GarbageCollector确实比垃圾处理更加明显,将它称为GarbageCollector几乎不公平.

总之:

我理解正确吗?还是我离开了?

如果我理解正确:为什么.NET开发人员称它为GarbageCollector?

.net garbage-collection

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

Thread.Abort()vs Application.Exitthread()

我知道只能在Thread中调用Exitthread,只要你可以访问Thread对象,就可以随时随地使用Abort.但是当你需要强制关闭一个线程时,这两个方法(操作方式)之间是否存在其他显着差异?

c# thread-abort

4
推荐指数
1
解决办法
2621
查看次数

Enum.GetValues中的意外行为或传递枚举

我正在编写一个与第三方程序交互的程序.该第三方程序允许用户制作可以在第三方程序中执行步骤记录的按钮.但!这些按钮还可以运行用户定义的批处理文件.因此,我使用此功能通过创建文件和检查这些文件是否存在来与我的程序进行交互.

我的程序包含两个类,一个Actionlistener和一个Actionperformer.actionperformer包含一个包含可能操作的枚举.

read函数如下所示:

static public void CheckForActions()
{
    //For every action in the Enum
    foreach (ActionPerformer.PossibleActions action in Enum.GetValues(typeof(ActionPerformer.PossibleActions)))
    {
        //If a file exists with the same name as the current action
        if (File.Exists(_location + action.ToString()))
        {
            //Delete "message" and create a new thread to perform this action.
            File.Delete(_location + action);
            Thread _t = new Thread(() => 
            { 
                new ActionPerformer(action);
            });

            _t.SetApartmentState(ApartmentState.STA);
            _t.Start();

            //Add thread to list so they can be joined propperly
            _list.Add(_t);

            //Write information to log …
Run Code Online (Sandbox Code Playgroud)

c# enums

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

这些有什么不同?

我在wcf服务中有这样的方法

public string PostAllSurveList(List<Survey> surveyList)
{
    var surveyDbList = ConstructDbServeyList(surveyList);
    foreach (var survey in surveyDbList)
    {
        _db.surveys.Add(survey);
    }
    _db.SaveChanges();
    return "Successfully Saved";
}
Run Code Online (Sandbox Code Playgroud)

当我通过以下方式在C#中调用此方法时,它工作正常

var surveys = new Survey[]{new Survey{ Id = 1, ConsumerName = "atish"},};

string reply = client.PostAllSurveList(surveys);
Run Code Online (Sandbox Code Playgroud)

但不是以下列方式工作

var surveys = new List<Survey>{ new Survey { Id = 1, ConsumerName = "atish"}};

string reply = client.PostAllSurveList(surveys);
Run Code Online (Sandbox Code Playgroud)

得到编译时错误.

我的问题是为什么会这样.

c# wcf

0
推荐指数
1
解决办法
69
查看次数