我有一个能够插件(MEF)的应用程序.插件是导入服务的WPF UserControls.
用户可以从应用程序的主菜单中选择所需的插件.
为此,我使用以下循环:
foreach(IToolPlugin Plugin in ToolPlugins)
{
Plugin.Init();
MenuItem PluginMenuItem = Plugin.MenuItem; //New MenuItem but with Header set.
PluginMenuItem.Click += new RoutedEventHandler(delegate(object o, RoutedEventArgs e) { DoSomething(Plugin.Control);});
PluginsMenu.Items.add(PluginMenuItem);
}
Run Code Online (Sandbox Code Playgroud)
这对于单个项目非常好.但是,只要我有一个以上的插件,所有菜单项都会执行最后一个循环的委托.或者至少使用最后一个循环的Plugin.Control.
我怎样才能解决这个问题?
谢谢你的帮助.
我试图同时运行几个任务,我遇到了一个似乎无法理解或解决的问题.
我以前有这样的功能:
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) 我正在使用SqlDataAdapter和DataSet从MSSQL服务器检索数据.从那个DataSet我创建了一个DataTable.我的目标是将表的每一列转换为字符串,其中元素以逗号分隔.我想我会在分隔符工作之前先尝试字符串转换.
代码在ASP.Net页面的代码隐藏中运行.最终的目标是将字符串传递给jscript变量,这是一个"功能需求",我从列创建一个分隔的字符串,并且它必须最终作为jscript变量.
这是我到目前为止所拥有的:
DataSet myDataSet = new DataSet();
mySqlDataAdapter.Fill(myDataSet);
DataTable temperature = myDataSet.Tables["Table"];
// LOOP1
foreach (DataRow row in temperature.Rows)
// this loop works fine and outputs all elements
// of the table to the web page, this is just to
// test things out
{
foreach (DataColumn col in temperature.Columns)
{
Response.Write(row[col] + " ### ");
}
Response.Write("<br>");
}
// LOOP2
foreach (DataColumn column in temperature.Columns)
// this loop was meant to take all elements for each
// column …Run Code Online (Sandbox Code Playgroud) 我在foreach循环中构建谓词时遇到了麻烦.包含枚举器当前所在值的变量是我需要在谓词中放置的内容.
所以,
IQueryable query = getIQueryableSomehow();
Predicate = PredicateBuilder.False<SomeType>();
foreach (SomeOtherType t in inputEnumerable)
{
Predicate = Predicate.Or( x => x.ListInSomeType.Contains(t) )
}
var results = query.Where(Predicate);
Run Code Online (Sandbox Code Playgroud)
我失败了.在Predicate中ORed一起使用的表达式基本上都是使用inputEnumerable中的相同t,当然我希望每个表达式ORed进入Predicate以使用与inputEnumerable不同的t.
我在循环之后查看调试器中的谓词,它看起来像IL.无论如何,那里的每个lambda看起来完全一样.
谁能告诉我这里可能做错了什么?
谢谢,
艾萨克
可能重复:
C#捕获的变量循环
我正在研究几个简单的线程应用程序,但我似乎无法让它工作:
class ThreadTest
{
static Queue<Thread> threadQueue = new Queue<Thread>();
static void Main()
{
//Create and enqueue threads
for (int x = 0; x < 2; x++)
{
threadQueue.Enqueue(new Thread(() => WriteNumber(x)));
}
while(threadQueue.Count != 0)
{
Thread temp = threadQueue.Dequeue();
temp.Start();
}
Console.Read();
}
static void WriteNumber(int number)
{
for (int i = 0; i < 1000; i++)
{
Console.Write(number);
}
}
}
Run Code Online (Sandbox Code Playgroud)
目标基本上是逐个向队列添加线程,然后逐个遍历队列并弹出一个线程并执行它.因为我的for循环中有"x <2",它应该只生成两个线程 - 一个运行WriteNumber(0),另一个运行WriteNumber(1),这意味着我应该以1000 0和我的屏幕上的1000 1是不同的顺序,具体取决于线程的最终执行方式.
我最终得到的是2000 2.我提出的两个可能的解决方案是:我错过了一些明显的东西,或者将变量x发送到WriteNumber函数正在执行pass-by-reference而不是pass-by-value,所以当线程执行它们使用最新版本的x而不是设置函数时的版本.但是,据我所知,变量在C#中默认按值传递,如果在参数中包含"ref",则仅通过引用传递.
我想试试看,这里发生了什么?编译器生成什么样的代码?
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.有人能给我一些编译器在这里做的伪代码吗?
谢谢.
假设螺纹形成4个单独的螺纹并等待它们中的每一个直到它们完成.每个线程都会休眠一段时间,只有当共享的Mutex opbject没有被另一个线程占用时才会终止,然后通过它完成的事件发出信号(这是我的代码的简化版本,但在同一个地方失败)
但是,大多数情况下主线程将在WaitOne()中的一个看似随机等待.
此外,我不得不将我的代码的某些部分注释掉,因为它导致了更多的意外行为(也就是说,在每个线程完成主线程之后会以某种方式跳回到for子句并导致IndexOutOfBounds)
class Threading
{
static Mutex CM;
static List<Manga> SharedList;
static ManualResetEvent CEvent = new ManualResetEvent(false);
static ManualResetEvent Event1 = new ManualResetEvent(false);
static ManualResetEvent Event2 = new ManualResetEvent(false);
static ManualResetEvent Event3 = new ManualResetEvent(false);
static ManualResetEvent Event4 = new ManualResetEvent(false);
public List<Manga> ThreadedMangaIndexCrawl(int MaxThreads)
{
CM = new Mutex(false);
SharedList = new List<Manga>();
ManualResetEvent[] evs = new ManualResetEvent[4];
evs[0] = Event1; // Event for t1
evs[1] = Event2; // Event for t2
evs[2] = Event3; // Event …Run Code Online (Sandbox Code Playgroud) 我有一个关于ActionC#中类型和Lambdas 的快速问题.这是代码:
static void Main(string[] args)
{
List<Action> actions = new List<Action>();
for (int I = 0; I < 10; I++)
actions.Add(new Action(() => Print(I.ToString())));
foreach (Action a in actions)
{
a.Invoke();
}
actions.Clear();
int X;
for (X = 0; X < 10; X++)
{
int V = X;
actions.Add(new Action(() => Print(V.ToString())));
}
foreach (Action a in actions)
{
a.Invoke();
}
Console.ReadLine();
}
public static void Print(string s)
{
Console.WriteLine(s);
}
Run Code Online (Sandbox Code Playgroud)
如果运行此代码,您将看到它连续十次输出10次,然后第二次输出数字0-9.它显然与我使用X vs I的方式有关,以及我如何在第二个循环中每次给我的动作一个新变量V ...可能每个新V都是内存中的新地址,但我是努力理解为什么I.ToString()在第一个循环中没有做同样的事情...为什么第一个Action中使用的I.ToString()与第二个例子的工作方式不一样?
场景:我正在构建一个调度系统和每个计时器事件,我想运行一个自定义方法而不是通常的Timer.Elapsed事件.
所以我写了这样的东西.
foreach (ScheduleElement schedule in schedules) {
TimeSpan timeToRun = CalculateTime(schedule);
schedule.Timer = new Timer(timeToRun.TotalMilliseconds);
schedule.Timer.Elapsed += delegate { Refresh_Timer(schedule); };
schedule.Timer.AutoReset = true;
schedule.Timer.Enabled = true;
}
Run Code Online (Sandbox Code Playgroud)
确实如此简单,实际上确实创造了我的计时器.但是,我希望每个已发生的事件都使用它传入的schedule元素运行.我的问题是,为什么Elapsed事件只传递每个Timer.Elapsed事件的for循环中的最后一个ScheduleElement.
现在我知道是什么修复它,我只是不确定为什么.如果我回滚到原始的Timer.Elapsed事件并使用我自己的类扩展Timer类,我可以解决它.像这样.
修复:
foreach (ScheduleElement schedule in schedules) {
TimeSpan timeToRun = CalculateTime(schedule);
schedule.Timer = new TimerEx(timeToRun.TotalMilliseconds);
schedule.Timer.Elapsed +=new System.Timers.ElapsedEventHandler(Refresh_Timer);
schedule.Timer.Tag = schedule;
schedule.Timer.AutoReset = true;
schedule.Timer.Enabled = true;
}
Run Code Online (Sandbox Code Playgroud)
然后我把它object sender放回原来的物体,然后把它Tag从它上面剥下来,这给了我每个独特计时器的正确时间表.
再说一遍,为什么在所有Timers的foreach循环delegate { }中使用最后一个传递ScheduleElement?
编辑1
Timer类
public TimerEx : …Run Code Online (Sandbox Code Playgroud) 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
c# ×10
lambda ×3
asynchronous ×2
delegates ×2
.net ×1
asp.net ×1
async-await ×1
closures ×1
datacolumn ×1
dataset ×1
datatable ×1
linq ×1
reference ×1
timer ×1
waitone ×1