gpt4 book ai didi

c# - 有没有办法使这段代码线程安全?

转载 作者:行者123 更新时间:2023-11-30 15:21:14 25 4
gpt4 key购买 nike

我正在创建一个带有进度条的 Windows 窗体程序,它将处理一个包含多行的文件。当我执行以下代码时,button2_Click 方法中的 progressBar1.Maximum 调用执行得很好,但 PostIncident 方法中的调用导致 System.InvalidOperationException,其中指出:“跨线程操作无效:从与创建它的线程不同的线程。”

到目前为止我尝试过的一些途径:1) 使 PostIncident 返回一个 bool 或 magic 值,以便我将 progressbar1.Maximum 调用拉到 button2_Click 方法中。我的问题是我的线程技能不足以解决从线程捕获返回值的问题。

2) 尝试在 PostIncident 方法中的 progressbar1.Maximum 调用周围放置一个锁或信号量,这导致了同样的错误。

目前我的解决方案是简单地从项目中完全删除线程,但我确信可能有一个优雅的解决方案,我只是太缺乏经验而看不到。

public partial class ExperianTriggerPoster : Form
{
private readonly OpenFileDialog _ofd = new OpenFileDialog();
public delegate void BarDelegate();
private string _path;

private void button1_Click(object sender, EventArgs e)
{
if (_ofd.ShowDialog() != DialogResult.OK) return;
textBox1.Text = _ofd.SafeFileName;
_path = _ofd.FileName;
}

private void button2_Click(object sender, EventArgs e)
{
string[] sAllLinesFromFile = File.ReadAllLines(_path);

foreach (string line in sAllLinesFromFile)
{
if (!line.StartsWith("N"))
{
progressBar1.Maximum -= 1;
continue;
}

//some logic here...
ThreadPool.QueueUserWorkItem(x => PostIncident(//some parameters here...));
}
}

private void PostIncident(//some parameters here...)
{
//some logic here...
if (customerNo == "not found") // must find a way to make this call thread-safe
{
Log.Information("Could not find customer# for user#: " + userNo);
progressBar1.Maximum -= 1;
}

Invoke(new BarDelegate(UpdateBar));
}

private void UpdateBar()
{
progressBar1.Value++;

if (progressBar1.Value != progressBar1.Maximum) return;

var postingComplete = MessageBox.Show("The posting is complete!", "Experian Trigger Poster", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
if (postingComplete == DialogResult.OK) Environment.Exit(0);
}
}

最佳答案

看看 Safe, Simple Multithreading in Windows FormsHow to: Make Thread-Safe Calls to Windows Forms Controls .

您想在 UI 线程上调用 UI 更新。

分割:

  • 将业务逻辑分离到一个类(业务层)中。例如:Bussiness1.cs
  • 为 UI 相关代码公开该类的公共(public)委托(delegate)。
  • 在 Form.cs(UI 层)中为您的业务类设置委托(delegate)值(在本例中为进度条更新)
  • 根据需要,类 (Business1.cs) 只需调用委托(delegate)。 (UI层实现)
  • UI线程安全:D

不知道这对您来说是否太高级了,但这确实可以帮助您以最佳实践编写代码。

关于c# - 有没有办法使这段代码线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38065443/

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