1

我有一个调用Func后台线程传递的方法,称为TaskSpin. DataGridView这会根据在(DGV)中单击的站点一次执行一种方法,并且一次只能执行一种方法。所以我点击一个站点(DGV 中的一个纽扣电池),然后它在该站点上运行该方法。现在我有很多站点,不想点击等待数百次,而是想批量处理 DGV 中包含的所有站点。我不能使用直接循环来运行这些,即

foreach (DataGridViewRow row in this.DGV)
    TaskSpin(SomeMethod, SomeParameterArray);

因为这几乎会立即返回给调用者,并将开始运行以下站点,这并不好,因为他们使用共享文件。所以我需要一种方法来将站点排队以逐个执行。我决定使用 a ConncurrentCollection - BlockingCollection,但我被卡住了。在某些按钮单击事件中,我有

BlockingCollection<Action<object[]>> taskQueue = 
    new BlockingCollection<Action<object[]>>();
List<object[]> paramQueue = new List<object[]>();
foreach (DataGridViewRow row in this.DataGridViewDrg.Rows) 
{
    paramQueue.Add(DrgDataRowInfo(row.Index));
    Action<object[]> action = new Action<object[]>(AsyncMethod);
    taskQueue.Add(action);
}
int i = 0;
foreach (Action<object[]> action in taskQueue.GetConsumingEnumerable())
    action(paramQueue[i]);

其中AsyncMethod使用 TPL 在后台线程上启动了一个 set 方法。

private void AsyncMethod(object[] siteInfo)
{
    TaskSpin(BuildDataForSite, siteInfo);
}

我的期望是这将一个Action<object[]>接一个地运行。但这只是冻结了我的申请。我在这里做错了什么?

谢谢你的时间。

*编辑。任务旋转*

public TaskSpin(Func asyncMethod, object[] methodParameters)
{
    ...
    asyncTask = Task.Factory.StartNew<bool>(() => 
        asyncMethod(uiScheduler, methodParameters));

    asyncTask.ContinueWith(task =>
    {
        ...
        // Finish the processing update UI etc.
        ...
    }
    ...
}
4

2 回答 2

3

编码

foreach (Action<object[]> action in taskQueue.GetConsumingEnumerable())
    action(paramQueue[i]);

正在您的 UI 线程上运行,从而导致阻塞。

您的要求似乎是您想在非 UI 线程上一次处理一个事物列表。要使用您当前的代码和最少的修改来实现这一点,您可以将上面的foreach移动到一个单独的线程中,例如通过创建一个运行foreach的任务。

Task.Factory.StartNew(() =>
{
    foreach (Action<object[]> action in taskQueue.GetConsumingEnumerable())
        action(paramQueue[i]);
});
于 2012-08-01T17:10:52.763 回答
0

虽然我迟到了

我的解决方案是使用Task.Run而不是Task.Factory.StartNew

Task.Run(() =>
{
    foreach (Action<object[]> action in taskQueue.GetConsumingEnumerable())
        action(paramQueue[i]);
});

我根据这篇文章发布这个答案

我也在使用Task.Factory.StartNew,但有时它会在我的 UI 线程上运行,导致我的应用程序挂起。Task.Run解决了我的问题。

于 2019-09-27T11:49:29.357 回答