让我们从一些源数据开始查询:
int[] someData = { 1, 2 };
Run Code Online (Sandbox Code Playgroud)
在运行以下代码之后,事情按照我的预期运行:a包含2个可归结为1和2从中拉出的元素someData.
List<IEnumerable<int>> a = new List<IEnumerable<int>>();
a.Add(someData.Where(n => n == 1));
a.Add(someData.Where(n => n == 2));
Run Code Online (Sandbox Code Playgroud)
但是下一个代码只在循环中执行完全相同的操作,并不能按预期工作.当此代码完成时,b包含2个元素,但它们都是相同的 - 指向2.在第二个循环中,它修改了第一个元素b.
List<IEnumerable<int>> b = new List<IEnumerable<int>>();
for (int i = 1; i <= 2; ++i)
{
b.Add(someData.Where(n => n == i));
}
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况?如何使循环版本像第一个版本一样?
我对正确的线程相对绿色,我有这个,它是为了简单而修改但它基本上是相同的东西:
//Global:
N=2
bool[] mySwitches;
//In my main:
mySwitches = new bool[N];
for (int i = 0; i < N; i++)
{
ThreadList.Add(new Thread(() => Worker(i)));
ThreadList[i].Start();
}
//Outside of main:
Private Void Worker(int num)
{
while(true)
{
if (mySwitches[num]) //error happes here because num is equal to N, how?
{
//do something
}
}
}
Run Code Online (Sandbox Code Playgroud)
如上所示,工作线程以某种方式得到num = N的值,我希望它只能达到N-1.我知道在创建Worker之后我会增加,是不是以某种方式通过引用而不是值传递?
我尝试通过在while循环之前进行测试来修复问题,如果num = N则返回,但即使使用此规定,我也会得到相同的错误.这让我相信在线程启动后,num会以某种方式递增.
我通过在ThreadList [i] .Start()之后直接放置Sleep(20)来解决这个问题,但我真的不喜欢使用Sleep,很明显我不知道这个线程场景是如何工作的.
任何人都可以对此有所了解吗?
class Program
{
static Action act = null;
static void Main(string[] args)
{
Test();
act();
act();
Test();
act();
}
static void Test()
{
int count = 0;
if(act == null) act = () => Console.Write(++count + " ");
}
}
Run Code Online (Sandbox Code Playgroud)
结果:1 2 3为什么?
如果delete[ if(act == null)]
结果:1 2 1
private static async Task FuncAsync(DataTable dt, DataRow dr)
{
try
{
await Task.Delay(3000); //assume this is an async http post request that takes 3 seconds to respond
Thread.Sleep(1000) //assume this is some synchronous code that takes 2 second
}
catch (Exception e)
{
Thread.Sleep(1000); //assume this is synchronous code that takes 1 second
}
}
Run Code Online (Sandbox Code Playgroud)
private async void Button1_Click(object sender, EventArgs e)
{
List<Task> lstTasks = new List<Task>();
DataTable dt = (DataTable)gridview1.DataSource;
foreach (DataRow dr in dt.Rows)
{
lstTasks.Add(FuncAsync(dr["colname"].ToString());
} …Run Code Online (Sandbox Code Playgroud) c# multithreading asynchronous task-parallel-library async-await
本周我参加了荷兰的TechDays 2013,我得到了一个有趣的测验问题.问题是:以下程序的输出是什么.这是代码的样子.
class Program
{
delegate void Writer();
static void Main(string[] args)
{
var writers = new List<Writer>();
for (int i = 0; i < 10; i++)
{
writers.Add(delegate { Console.WriteLine(i); });
}
foreach (Writer writer in writers)
{
writer();
}
}
}
Run Code Online (Sandbox Code Playgroud)
显然,我给出的答案是错误的.我认为,因为int是一个值类型,传递的实际值Console.WriteLine()被复制,所以输出将是0 ... 9.但是i在这种情况下作为参考类型处理.正确答案是它会显示十次10.有人可以解释为什么以及如何解释?
我正在开发一个WinForm项目,我在for循环中有一个标签.我想在执行label.text语句后每次都显示标签.但它并不是每次都显示,而是在for循环结束后显示.
我尝试通过使用来实现这一点Thread.Sleep().但我不能.请帮我.注意: - lblProgress是一个标签
这是我的编码.
for (int i = 1; i <= sourceTable.Rows.Count - 1; i++)
{
string checkout;
checkout= sourceTable.Rows[i].Field<string>(0);
dest = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["local"].ConnectionString);
dest.Open();
destcmd = new SqlCommand(checkout, dest);
destcmd.ExecuteNonQuery();
dest.Close();
prcmail();
prcmessagecheck();
lblProgress.Text = "Hello World"+i;
Thread.Sleep(10000);
}
Run Code Online (Sandbox Code Playgroud) 我浏览了一些 C# 示例并发现了以下内容:
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
class Program
{
delegate void Printer();
static void Main()
{
List<Printer> printers = new List<Printer>();
for (int i = 0; i < 10; i++)
{
printers.Add(delegate { var d = i; Console.WriteLine(d); });
}
foreach (var printer in printers)
{
printer();
}
Console.ReadLine();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我期望它0通过输出9,因为 anint是一种值类型,d应该设置为i当时的任何值。
然而,这输出了10十倍。
为什么是这样?int 不是一个引用而是在委托内部吗?
注意:我并不是想在这里解决问题,只是以可重复应用的方式了解它是如何工作的。
编辑:我的困惑的例子
int i = …Run Code Online (Sandbox Code Playgroud) 为什么这不完整?相反,它抛出一个异常,就像没有捕获异常一样.而且,"索引超出数组范围"的例外对我来说没有意义.
int n = 3;
string[] names = new string[] { "sally", "fred", "gina" };
Task[] myTasks = new Task[n];
for (int y = 0; y < n; y++)
{
myTasks[y] = Task.Factory.StartNew(() =>
{
Action<string> action = (name) =>
{
try
{
throw new Exception(name + ", I bet you can't catch me.");
}
catch (Exception e)
{
//I caught you... didn't I?
}
};
action(names[y]);
});
}
Task.WaitAll(myTasks);
Console.WriteLine("All tasks complete.");//This line is never reached;
Run Code Online (Sandbox Code Playgroud) int[] div = new int[] {2,3,5};
IEnumerable<int> seq = new int[] {10,15,20,25,30};
int x;
for (int i=0; i<div.Length; i++){
x = div[i];
seq = seq.Where( s=> s%x ==0);
}
seq = seq.ToList();
Run Code Online (Sandbox Code Playgroud)
和
int[] div = new int[] {2,3,5};
IEnumerable<int> seq = new int[] {10,15,20,25,30};
for (int i=0; i<div.Length; i++){
int y = div[i];
seq = seq.Where( s=> s%y ==0);
}
seq = seq.ToList();
Run Code Online (Sandbox Code Playgroud)
第一个seq的最终值是10,15,20,25,30,第二个是30.我对int x;
和 之间的区别有点困惑int y = div[i];.谁可以给我解释一下这个?
谢谢!
我的C#程序运行一个进程,当单击特定按钮时,该进程启动一个命令提示符应用程序,并向其传递参数。
程序从用户选择中获取目录路径,并检查它是否为空。
如果它不为空,则 foreach 循环将循环遍历目录中每个文件的完整路径数组。它还会将进度条设置为 0 并准备好进行增量
当它循环时,它将运行cli-taskusing Process
问题是:完成循环文件的任务后,我希望它删除该文件并增加进度条。
如果像这样一一进行的话,效果很好:
process.WaitForExit(10000);
File.Delete(fileName);
progressBar1.Increment(1);
Run Code Online (Sandbox Code Playgroud)
但该程序非常慢。因为它会等待每个进程完成后再开始下一个进程。
所以我尝试了下面的代码:
string[] files = Directory.GetFiles(label1.Text);
if (files.Length != 0)
{
progressBar1.Value = 0;
progressBar1.Minimum = 0;
progressBar1.Maximum = files.Length;
foreach (string fileName in files)
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
//startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = @"C:\Program Files\cli-tool\cli.exe";
startInfo.Arguments = "-i " + "\"" + fileName + "\"" + " -o " + "\"" + label2.Text + …Run Code Online (Sandbox Code Playgroud) c# ×10
.net ×1
async-await ×1
asynchronous ×1
delegates ×1
for-loop ×1
lambda ×1
linq ×1
task ×1
value-type ×1
winforms ×1