gpt4 book ai didi

c# - 从 DoWork 处理程序调用方法?

转载 作者:行者123 更新时间:2023-11-30 21:59:44 24 4
gpt4 key购买 nike

我正在尝试使用 BackgroundWorker 来完成一项任务。我已经让 worker 正确运行,在 DoWork 方法下它然后调用另一个执行的方法但后来我遇到了我的问题:当该方法试图调用另一个方法时它没有成功并且没有抛出一个异常,我只能认为这是我在 BackgroundWorker 上做错的事情,因为在 UI 线程上运行以测试方法是否按预期执行。

这是我运行 worker 的地方:

private void btnAddShots_Click(object sender, EventArgs e)
{
backgroundWorker.RunWorkerAsync();
}

这是我的 DoWork 方法:

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
int noOfShots = dataGridShots.Rows.Count - 1;
int count = 0;

while (count < noOfShots)
{
addTaskPair(dataGridShots.Rows[count].Cells[0].Value.ToString(),
dataGridShots.Rows[count].Cells[1].Value.ToString(),
dataGridShots.Rows[count].Cells[2].Value.ToString());

count += 1;
}
}

这是我的工作人员调用的 addTaskPair 方法的精简版:

private void addTaskPair(string taskName, string taskDescription, string taskPriority)
{
try
{
Task trackingTask = new Task();

trackingTask.content = taskName;
trackingTask.description = taskDescription;
trackingTask.priority = taskPriority;

string trackingJson = JsonConvert.SerializeObject(trackingTask);
trackingJson = "{ \"todo-item\":" + trackingJson + " }";

string jsonResponse;
jsonResponse = postJSON(trackingJson, teamworkURL + "/tasklists/"
+ todoLists.todoLists[cmbTrackingList.SelectedIndex].id + "/tasks.json");
}
catch (Exception e)
{
debugMessage(e.ToString());
}
}

在上面的示例中,您会看到我调用了方法 postJSON,这就是我碰壁的地方。通过测试,我已经验证了上述方法运行,但是从该线程中调用时 postJSON 方法根本不运行。

在研究这个问题时,我已经看到很多关于 Invoking 的引用,但它们似乎都适用于更改我不需要做的 ui 控件(尽管进度条是使用 操作的) ProgressChanged BackgroundWorker 事件)。

如果需要,我可以进一步澄清我的问题,但我真的希望得到这方面的帮助,因为我以前从未成功地使用过 backgroundworker 或线程(我不是专业人士,我相信你可以从我的代码中看出) .

最佳答案

您正在使用 BackgroundWorker.DoWork 事件处理程序中的 UI 控件。不要那样做。

在启动 BackgroundWorker 之前收集数据,并将其作为参数传递给 RunWorkerAsync 方法。不要触摸 BackgroundWorker.DoWork 中的 UI - 通过 ReportProgress 方法更新进度是可以的。

此外,如果您在 .NET 4.5+ 上运行,您可能需要考虑改用新的 Task 模式。它仍然需要您事先收集数据进行处理,但使用起来要容易得多:

(编辑:正如 Peter 所建议的,无效访问发生在 cmbTrackingList.SelectedIndex 中;我已将其包含在下面的代码中。这正是我建议的原因对发生在单独线程中的操作使用 static 方法 - 这会让您对正在处理的数据有更多的思考)

var todoList = todoLists.todoLists[cmbTrackingList.SelectedIndex];

var data =
dataGridShots
.Rows
.Select
(
i =>
new
{
TaskName = i.Cells[0].Value.ToString(),
TaskDescription = i.Cells[1].Value.ToString(),
TaskPriority = i.Cells[2].Value.ToString()
}
)
.ToArray();

var result =
await Task.Run
(
() =>
foreach (var row in data)
handleRowData(row.TaskName, row.TaskDescription, row.TaskPriority, todoList)
);

既然你已经走到这一步了,你可能会注意到让你的 postJson 方法异步也不难(有很多方法可以异步发出 HTTP 请求)——这个将允许您在不阻塞任何线程的情况下使整个代码异步。

多线程困难。始终尝试使用尽可能高的抽象,并避免任何共享状态。如果您确实需要共享状态,您需要同步每个线程对它的每次访问 - 尽量避免这种情况(一个好的做法是让方法在不同的线程上执行 static ,这样你就不会不小心触及共享状态)。

关于c# - 从 DoWork 处理程序调用方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29079330/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com