相关疑难解决方法(0)

ThreadPool.QueueUserWorkItem的意外行为

请检查下面的代码示例:

public class Sample
{
    public int counter { get; set; }
    public string ID;
    public void RunCount()
    {
        for (int i = 0; i < counter; i++)
        {
            Thread.Sleep(1000);

            Console.WriteLine(this.ID + " : " + i.ToString());
        }
    }
}

class Test
{
    static void Main()
    {
        Sample[] arrSample = new Sample[4];

        for (int i = 0; i < arrSample.Length; i++)
        {
            arrSample[i] = new Sample();
            arrSample[i].ID = "Sample-" + i.ToString();
            arrSample[i].counter = 10;
        }

        foreach (Sample s in arrSample) …
Run Code Online (Sandbox Code Playgroud)

.net c# multithreading asynchronous threadpool

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

循环中的Lambda变量捕获 - 这里发生了什么?

我想试试看,这里发生了什么?编译器生成什么样的代码?

public static void vc()
{
    var listActions = new List<Action>();

    foreach (int i in Enumerable.Range(1, 10))
    {
        listActions.Add(() => Console.WriteLine(i));
    }

    foreach (Action action in listActions)
    {
        action();
    }
}

static void Main(string[] args)
{ 
  vc();
}
Run Code Online (Sandbox Code Playgroud)

输出: 10 10 .. 10

根据这个,ActionHelper的新实例会为每次迭代创建.那么在这种情况下,我认为它应该打印1..10.有人能给我一些编译器在这里做的伪代码吗?

谢谢.

.net c# lambda

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

Foreach中的C#动作

fMethod是一个Action<Fruit>.

但是当fMethod调用时,参数始终是最后一个条目_Fruits.
怎么解决这个?

foreach(Fruit f in _Fruits)
{
   field.Add(new Element(f.ToString(),delegate{fMethod(f);}));
}
Run Code Online (Sandbox Code Playgroud)

c# foreach delegates action

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

在闭包中,是什么触发了捕获变量的新实例?

我正在深入阅读Jon Skeet的C#.

在页156,他有一个例子,清单5.13"捕获多个委托的多个变量实例".

List<ThreadStart> list = new List<ThreadStart>();

for(int index=0; index < 5; index++;)
{
    int counter = index*10;
    list.Add(delegate
          {
              Console.WriteLine(counter);
              counter++;
          }
        );
}

foreach(ThreadStart t in list)
{
    t();
}

list[0]();
list[0]();
list[0]();

list[1]();
Run Code Online (Sandbox Code Playgroud)

在此列表之后的解释中,他说"在这种情况下,每个委托实例都捕获了一个不同的变量."

我理解这一点很好,因为我理解每次你关闭一个变量时,编译器会生成IL,将其封装在一个新的类中,专门用于允许捕获该变量(实质上使它成为一个引用类型,以便它引用的值)不会被当前执行范围的堆栈框架破坏).

但后来他谈到了如果我们index直接捕获而不是创建counter变量会发生什么- "所有代表都会共享相同的变量".

这个我不明白.是不是index在同一范围内counter?为什么编译器也不会index为每个委托创建一个新实例?


注意:我想我在输入这个问题时想出来了,但我会在这里留下问题给后人.我认为答案index实际上是在不同的范围内counter.索引基本上是在for循环中"声明"...每次都是相同的变量.

看一下为for循环生成的IL ,它证明变量是在循环外声明的(length并且i是在for循环声明中声明的变量).

.locals init (
    [0] int32 length,
    [1] int32 …
Run Code Online (Sandbox Code Playgroud)

c# closures

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

访问Lambda表达式中的Modified Closure

foreach(var category in categories) {
    a.AddRange(_db.Articles.Where(c => c.Categories.Contains(category)));
}
Run Code Online (Sandbox Code Playgroud)

代码运行正常,但我category在lambda表达式中使用的引用中收到了关于"访问修改后的闭包"的警告.

问题:在这种情况下是否有任何后果的警告?

c# linq lambda closures

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

为什么我会得到:"lambda表达式中的迭代变量可能会产生意外结果"

可能重复:
为什么在lambda表达式中使用迭代变量是不好的

为什么我会得到:"lambda表达式中的迭代变量可能会产生意外结果"?假设我有以下代码:

  Dim writeAbleColumns As String() = {"IsSelected", "IsFeeExpense", "IsSubscriptionRedemption"}
  With grid
     For Each column As DataGridViewColumn In .Columns
      column.ReadOnly = Not Array.Exists(writeAbleColumns, Function(arrElement) column.Name = arrElement)
      Next
  End With
Run Code Online (Sandbox Code Playgroud)

我收到警告:

Warning 1   Using the iteration variable in a lambda expression may have unexpected results.  Instead, create a local variable within the loop and assign it the value of the iteration variable.
Run Code Online (Sandbox Code Playgroud)

我不明白为什么将我的代码更改为以下更改:

  Dim writeAbleColumns As String() = {"IsSelected", "IsFeeExpense", "IsSubscriptionRedemption"}
  With grid
     For Each column As DataGridViewColumn In …
Run Code Online (Sandbox Code Playgroud)

.net vb.net

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

为什么局部变量?

resharper让我把它变成一个局部变量,写下"访问修改后的闭包"

if (filter != null)
{
    if (filter.CityId != 0)
    {
        ads = ads.Where(x => x.Ad.CityId == filter.CityId);
    }
    if (filter.BusinesCategoryId != 0)
    {
        ads = ads.Where(x => x.BusinessCategoryId == filter.BusinesCategoryId);
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么局部变量过滤?

c# linq filter

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

Linq与字典奇怪的behviour

我遇到了Linq的一个奇怪的行为:有两个linq表达式可能看起来相同,我有不同的结果!如果我循环一次我得到相同的结果,但在上面它什么都没发现.

这是代码:

        Dictionary<String, String> mainDico = new Dictionary<String, String>();
        mainDico.Add("key1", "value1");
        mainDico.Add("key2", "value2");

        List<Dictionary<String, String>> ls = new List<Dictionary<String, String>>();

        Dictionary<String, String> fistDico = new Dictionary<String, String>();
        fistDico.Add("key1", "value1");
        fistDico.Add("key2", "value2");

        Dictionary<String, String> secondDico = new Dictionary<String, String>();
        secondDico.Add("key1", "other");
        secondDico.Add("key2", "other");

        ls.Add(fistDico);
        ls.Add(secondDico);


        IEnumerable<Dictionary<String, String>> failQuery = from p in ls
                                                            select p;

        IEnumerable<Dictionary<String, String>> successfulQuery = from p in ls
                                                            select p;

        String[] items = new String[] { "key1","key2" }; // with one element it works

        foreach (var …
Run Code Online (Sandbox Code Playgroud)

c# linq dictionary

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

关于关闭的for和foreach之间有什么区别

演示代码有一些问题.

var values = new List<int>() { 100, 110, 120 };  
var funcs = new List<Func<int>>();  

foreach(var v in values)   
    funcs.Add( ()=>v );  

foreach(var f in funcs)   
    Console.WriteLine(f());  
Run Code Online (Sandbox Code Playgroud)

大多数人认为它是100/110/120.实际上是120/120/120.

但是vs2015和.net 4.5.1的结果将输出 100/110/120 ,而不是 120/120/120 .

当我按如下方式测试代码时,for和之间存在一些差异foreach

var values = new List<int> {100, 110, 120};

var funcs = new List<Func<int>>();
foreach (var v in values)
    funcs.Add(() =>
    {
        Console.WriteLine(v);
        return v;
    } );

foreach (var f in funcs)
    Console.WriteLine(f());

//will throw exception
for (int i=0;i<values.Count;i++)
    funcs.Add(() => …
Run Code Online (Sandbox Code Playgroud)

c# foreach lambda closures for-loop

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

执行forloop时发生IndexOutOfRangeException

IEnumerable<char> query = "Not what you might expect";
string vowels = "aeiou";
for (int i = 0; i < vowels.Length; i++)
query = query.Where (c => c != vowels[i]);
foreach (char c in query) Console.Write (c);
Run Code Online (Sandbox Code Playgroud)

发生异常IndexOutOfRangeException。为什么会发生这个异常,一切看起来都很好。

提前致谢。

解决方案

for (int i = 0; i < vowels.Length; i++)
{
char vowel = vowels[i];
query = query.Where (c => c != vowel);
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,这些代码有什么区别。请分享详细信息。

.net c#

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