相关疑难解决方法(0)

如何在lambda表达式中捕获外部变量的值?

我刚刚遇到以下行为:

for (var i = 0; i < 50; ++i) {
    Task.Factory.StartNew(() => {
        Debug.Print("Error: " + i.ToString());
    });
}
Run Code Online (Sandbox Code Playgroud)

将导致一系列"错误:x",其中大多数x等于50.

同理:

var a = "Before";
var task = new Task(() => Debug.Print("Using value: " + a));
a = "After";
task.Start();
Run Code Online (Sandbox Code Playgroud)

将导致"使用价值:之后".

这显然意味着lambda表达式中的串联不会立即发生.在声明表达式时,如何在lambda表达式中使用外部变量的副本?以下内容不会更好(我承认这不一定是不连贯的):

var a = "Before";
var task = new Task(() => {
    var a2 = a;
    Debug.Print("Using value: " + a2);
});
a = "After";
task.Start();
Run Code Online (Sandbox Code Playgroud)

c# lambda closures asynchronous task-parallel-library

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

带参数的Dispatch.Invoke(new Action ...)

以前我有过

Dispatcher.Invoke(new Action(() => colorManager.Update()));
Run Code Online (Sandbox Code Playgroud)

从另一个线程更新显示到WPF.由于设计,我不得不改变程序,我必须将ColorImageFrame参数传递给我的ColorStreamManager.Update()方法.

链接之后,我将我的调度程序修改为:

Dispatcher.Invoke(new Action<ColorStreamManager, ColorImageFrame>((p,v) => p.Update(v)));
Run Code Online (Sandbox Code Playgroud)

它编译得很好但根本不会运行.VS2010说"参数计数不匹配".在我的ColorStreamManager.Update()方法中,我有 RaisePropertyChanged(() => Bitmap);

有人可以指出我哪里出错了吗?

ColorStreamManager.Update()方法的签名如下:

 public void Update(ColorImageFrame frame);
Run Code Online (Sandbox Code Playgroud)

.net c# wpf multithreading

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

带有索引参数的 Blazor/razor onclick 事件

我有下面的代码,但是当我单击该<tr>元素时传递的索引参数始终为 9。

这是因为表中有 9 行作为数据传递给组件。所以看起来索引总是最后设置的变量“i”的值...在这种情况下,foreach循环中最后一行之后的i的值是9,所以我在单击所有按钮时得到索引参数为9表中的行...

我的代码中的问题是什么,没有i为每行 onclick 设置值。

    <table border="1">

        @for(int i=0;i< ListData.DataView.Table.Rows.Count; i++)
        {
            <tr @onclick="(() => RowSelect(i))">
                @foreach (ModelColumn col in ListData.ListColumns)
                {
                    <td>@ListData.DataView.Table.Rows[i][col.Name]</td>
                }
            </tr>
        }

    </table>
Run Code Online (Sandbox Code Playgroud)
@code {
 
    private async Task  RowSelect(int rowIndex)
    {
        await ListRowSelected.InvokeAsync(rowIndex);
    }
}
Run Code Online (Sandbox Code Playgroud)

c# razor-pages blazor-server-side

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

循环中的匿名c#委托

大家好我想写和匿名代表.因为整数变量在委托之间共享,我需要它是每个委托的本地实例,这样rs [0]总是得到nics [0],rs [1]总是得到nics [1]等等...我会实现这一目标吗?

for (int i = 0; i < nics.Count; i++)
   {
         rs[i] = new RollingSeries(monitor, new RollingSeries.NextValueDelegate(delegate()
         {
            return GetNetworkUtilization(nics[i]);
          }));
    }
Run Code Online (Sandbox Code Playgroud)

阿卜杜勒·卡利克

c# delegates

13
推荐指数
2
解决办法
5594
查看次数

C#使用Continue在try catch中捕获

现在,我对continue语句有一个重大问题.FetchUnseenMessages可能会也可能不会返回错误,具体取决于它是否能够连接到指定的电子邮件帐户.如果FetchUnseenMessages失败,我希望continue语句返回到foreach语句中的下一个项目(尝试下一个电子邮件帐户).我得到了一些意想不到的结果.我不相信continue语句会转到foreach语句中的下一个项目,但会回到try语句的开头并再次尝试它.我整天都被困在这里,而且我很困难.请帮忙.谢谢,克里斯.

foreach (string l in lUserName)
{ 
    try
    {
        newMessages = FetchUnseenMessages(sUsername);
    }
    catch
    {
        continue;
    }

    //Other code
}
Run Code Online (Sandbox Code Playgroud)

c# asp.net

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

C#lambda,当你想到的时候没有采用局部变量值?

鉴于:

void AFunction()
{

   foreach(AClass i in AClassCollection)
   {
      listOfLambdaFunctions.AddLast(  () =>  {  PrintLine(i.name); }  );
   }
}

void Main()
{
    AFunction();
    foreach( var i in listOfLambdaFunctions)
       i();
}
Run Code Online (Sandbox Code Playgroud)

现在你会认为这样做会对等:

void Main()
{

    foreach(AClass i in AClassCollection)
       PrintLine(i.name);
}
Run Code Online (Sandbox Code Playgroud)

但它没有,它将做的是每次打印AClassCollection中最后一项的名称!所以基本上每个lambda函数都使用相同的项目.我怀疑"当lambda被创建时"或"当它使用其中使用的外部变量的快照时"可能会有一些延迟,或者基本上只是持有'对局部变量的引用'i'

所以我这样做了:

string astr = "a string";
AFunc fnc = () => { System.Diagnostics.Debug.WriteLine(astr); };
astr = "changed";
fnc();
Run Code Online (Sandbox Code Playgroud)

而惊喜,惊喜,它输出"改变了!"

我正在使用XNA 3.1(无论是什么c#)

到底是怎么回事?lambda函数以某种方式存储变量或其他东西的"引用"吗?反正这个问题呢?

c# lambda

12
推荐指数
3
解决办法
9909
查看次数

对C#循环中的多线程感到困惑

可能重复:
C#捕获的变量循环

我对多线程编程很陌生.当我运行下面的代码,只有最后一个孩子被执行.有人可以告诉我发生了什么吗?非常感谢你.

private void Process()
{
    Dictionary<int, int> dataDict = new Dictionary<int, int>();
    dataDict.Add(1, 2000);
    dataDict.Add(2, 1000);
    dataDict.Add(3, 4000);
    dataDict.Add(4, 3000);

    foreach (KeyValuePair<int, int> kvp in dataDict)
    {
        Console.WriteLine("Ready for [" + kvp.Key.ToString() + "]");
        Task.Factory.StartNew(() => DoSomething(kvp.Value, kvp.Key));
    }

private static void DoSomething(int waitTime, int childID)
{
    {               
        Console.WriteLine("Start task [" + childID.ToString() + "]");
        Thread.Sleep(waitTime);
        Console.WriteLine("End task [" + childID.ToString() + "]");
    }
}
Run Code Online (Sandbox Code Playgroud)

产量


Ready for [1]
Ready for [2]
Ready for [3]
Ready for [4] …
Run Code Online (Sandbox Code Playgroud)

c# multithreading

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

Linq多个查询位置

我有一个问题,建立一个相当沉重的linq查询.基本上我有一种情况,我需要在循环中执行子查询以过滤从数据库返回的匹配数.示例代码在以下循环中:

        foreach (Guid parent in parentAttributes)
        {
            var subQuery = from sc in db.tSearchIndexes
                           join a in db.tAttributes on sc.AttributeGUID equals a.GUID
                           join pc in db.tPeopleIndexes on a.GUID equals pc.AttributeGUID
                           where a.RelatedGUID == parent && userId == pc.CPSGUID                             
                           select sc.CPSGUID;

            query = query.Where(x => subQuery.Contains(x.Id));
         }
Run Code Online (Sandbox Code Playgroud)

当我随后在查询变量上调用ToList()时,似乎只执行了一个子查询,并且我留下了一大堆我不需要的数据.但是这种方法有效:

       IList<Guid> temp = query.Select(x => x.Id).ToList();

        foreach (Guid parent in parentAttributes)
        {
            var subQuery = from sc in db.tSearchIndexes
                           join a in db.tAttributes on sc.AttributeGUID equals a.GUID
                           join pc in db.tPeopleIndexes on a.GUID …
Run Code Online (Sandbox Code Playgroud)

.net c# linq entity-framework-4

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

在循环内启动任务:如何传递可在循环内更改的值?

我试图在while循环中使用TPL,我需要将一些值传递给任务然后更改为循环.例如,这里显示了一个增加索引的示例(必须在请求创建任务的行之后):

int index = 0;
Task[] tasks;
while(/*condition*/)
{
    tasks[index] = Task.Factory.StartNew(() => DoJob(index));
    index++;
}
Run Code Online (Sandbox Code Playgroud)

但当然它不起作用,因为索引值可以在任务开始之前递增.一个可能的解决方案可能是在递增索引之前传递一个等待的WaitHandle,并且必须在DoJob方法中发出信号,但在我看来这不是一个非常好的解决方案.还有其他想法吗?

c# task task-parallel-library

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

异步lambda中的参数

我试图同时运行几个任务,我遇到了一个似乎无法理解或解决的问题.

我以前有这样的功能:

private void async DoThings(int index, bool b) {
    await SomeAsynchronousTasks();
    var item = items[index];
    item.DoSomeProcessing();
    if(b)
        AVolatileList[index] = item; //volatile or not, it does not work
    else
        AnotherVolatileList[index] = item;
}
Run Code Online (Sandbox Code Playgroud)

我想用for循环调用Task.Run().但是我找不到向这个发送参数的方法,Action<int, bool>并且每个人都建议在类似的情况下使用lambdas:

for(int index = 0; index < MAX; index++) { //let's say that MAX equals 400 
    bool b = CheckSomething();
    Task.Run(async () => {
        await SomeAsynchronousTasks();
        var item = items[index]; //here, index is always evaluated at 400
        item.DoSomeProcessing();
        if(b)
            AVolatileList[index] …
Run Code Online (Sandbox Code Playgroud)

c# lambda asynchronous

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