标签: backgroundworker

线程不活动时释放资源

我正在使用 BackgroundWorker 并在其中使用 foreach 循环,在其中我创建新线程,等待它完成,然后报告进度并继续 foreach 循环。这就是我要说的:

private void DoWork(object sender, DoWorkEventArgs e) {
            var fileCounter = Convert.ToDecimal(fileNames.Count());
            decimal i = 0;
            foreach (var file in fileNames) {
                i++;
                var generator = new Generator(assembly);

                var thread = new Thread(new ThreadStart(
                        delegate() {
                            generator.Generate(file);
                        }));
                thread.SetApartmentState(ApartmentState.STA);
                thread.Start();
                while (thread.IsAlive); // critical point
                int progress = Convert.ToInt32(Math.Round(i / fileCounter * 100));
                backgroundWorker.ReportProgress(progress);
            }
        }
Run Code Online (Sandbox Code Playgroud)

问题是线程完成后(通过“临界点”线后)内存没有被释放。我认为当线程不活动时,与它相关的所有资源都会被释放。但显然这不是真的。任何人都可以向我解释为什么以及我做错了什么。谢谢。

c# multithreading backgroundworker

1
推荐指数
1
解决办法
3016
查看次数

BackGroundWorker 线程中的 ShowDialog 和 UI 交互

经过2个小时的研究,我仍然找不到解决我的问题的方法。

我所做的任务是在 BackGroundWorker 线程中处理一些文件。但是,有时我需要使用 ShowDialog 让用户选择 SaveFile 位置,但我收到 STA/MTA 错误。

主窗体代码:

private void button2_Click(object sender, EventArgs e)
{
            button1.Enabled = false;
            ProcessReportWorker.RunWorkerAsync();
}
Run Code Online (Sandbox Code Playgroud)

工作代码:

void ProcessReportWorker_DoWork(object sender, DoWorkEventArgs e)
{
    int ReportCount = Reports.Count();
    foreach (string Report in Reports)
    {
            ProcessReport NewReport = new ProcessReport(Report);
        string result = NewReport.Start();
    }
} 
Run Code Online (Sandbox Code Playgroud)

ProcessReport.Start() 代码:

class ProcessReport
{
    public string Start() 
    {
        if(File.Exists(ResultPath))
        {
            SaveFileDialog SaveReport = new SaveFileDialog();
                    SaveReport.InitialDirectory = "c:\somepath";
                    SaveReport.CheckPathExists = true;
                    SaveReport.DefaultExt = ".xls";
                    SaveReport.OverwritePrompt = true;
                    SaveReport.ValidateNames …
Run Code Online (Sandbox Code Playgroud)

c# multithreading backgroundworker sta showdialog

1
推荐指数
1
解决办法
5977
查看次数

在后台工作线程中访问主线程控制

我有一个ShowPanel(Control ctrl)需要Control作为参数传递的函数。我需要在后台工作线程中调用这个函数。我使用以下代码

void bw_DoWork(object sender,DoWorkEventArgs e)
{                      
    ShowPanel(listBox1);           
}
Run Code Online (Sandbox Code Playgroud)

但因执行而失败

跨线程操作无效:从创建它的线程以外的线程访问控件“Form1”

我怎样才能listBox1在后台线程中通过这里?

c# multithreading backgroundworker winforms

1
推荐指数
1
解决办法
6240
查看次数

具有高性能的 Winforms 更新

让我用一些背景信息来设置这个问题,我们有一个长时间运行的进程,它将在 Windows 窗体中生成数据。因此,显然需要某种形式的多线程来保持表单响应。但是,我们还要求表单每秒更新多次,同时仍然保持响应。

这是一个使用后台工作线程的简单测试示例:

void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        int reportValue = (int)e.UserState;
        label1.Text = reportValue;
        //We can put this.Refresh() here to force repaint which gives us high repaints but we lose
        //all other responsiveness with the control

    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
            for (int x = 0; x < 100000; x++)
            {     
              //We could put Thread.Sleep here but we won't get highest performance updates
                bw.ReportProgress(0, x);                    
            }
    }
Run Code Online (Sandbox Code Playgroud)

请查看代码中的注释。另外,请不要问我为什么要这个。问题很简单,我们如何在保持响应性的同时在更新表单时实现最高保真度(最多重绘)?强制重绘确实为我们提供了更新,但我们不处理 Windows 消息。

我也尝试放置 DoEvents,但这会产生堆栈溢出。我需要的是某种说法,“如果您最近没有处理任何 Windows 消息”。我也可以看到,可能需要稍微不同的模式来实现这一点。

看来我们需要处理几个问题: …

multithreading backgroundworker winforms task-parallel-library

1
推荐指数
1
解决办法
2150
查看次数

“必须在与 DependencyObject 相同的线程上创建 DependencySource。” 绑定背景时

我想更改 Backgroundworker 中数据网格的标签和背景。我有这样的网格:

<Grid HorizontalAlignment="Center" Height="499" Margin="96,170,810,0" VerticalAlignment="Top" Width="486" Background="{Binding aBackGround}">
    <Label Content="212" FontSize="100"  HorizontalAlignment="Left" VerticalAlignment="Top" RenderTransformOrigin="-4.395,-11.154" Margin="173,22,0,0" Height="123" Width="178"/>
    <Label Content="{Binding aPace}" FontSize="65"  HorizontalAlignment="Left" VerticalAlignment="Top" Margin="23,202,0,0" Height="84" Width="255"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)

在后面的代码中,我有 aBackGround 和 aPace,如下所示:

private Brush _aBackGround;
private string _apace;

public Brush aBackGround
{
    get { return _aBackGround; }
    set
    {
        _aBackGround= value;
        RaisePropertyChanged(() => this.aBackGround);    
    }
}

public string aPace
{
    get { return _apace; }
    set
    {
        _apace = value;
        RaisePropertyChanged(() => this.aPace);
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以正确地看到 aPace 的结果,但一秒钟后我得到 …

c# wpf multithreading backgroundworker

1
推荐指数
1
解决办法
3898
查看次数

如何从BackgroundWorker线程中更新标签?

当我使用WinForms时,我会在我的bg_DoWork方法中完成这个:

status.Invoke(new Action(() => { status.Content = e.ToString(); }));
status.Invoke(new Action(() => { status.Refresh(); }));
Run Code Online (Sandbox Code Playgroud)

但是在我的WPF应用程序中,我得到一个错误,Invoke说不存在Label.

任何帮助,将不胜感激.

c# wpf xaml backgroundworker

1
推荐指数
1
解决办法
2140
查看次数

计算的进度百分比未更新

我正在尝试显示标签中后台工作人员的进度百分比值。我正在添加 Aprox。数据表 25 K 行。当我仅将 Label.Text 设置为 e.ProgressPercentage 时,它​​工作正常。但是当我计算%值时,它保持不变。只有在worker完成后标签才更新为100%

                progressCount = report.Rows.Count;
                foreach (DataRow r in report.Rows)
                {

                        rp.pName = r[1].ToString();
                        rp.batch = r[2].ToString();
                        rp.expr = r[3].ToString();
                        rp.stock = r[5].ToString();
                        rp.rate = r[6].ToString();
                        backgroundWorker2.ReportProgress(i, rp);
                        System.Threading.Thread.Sleep(2);
                        if(backgroundWorker2.CancellationPending)
                        {
                            e.Cancel = true;
                            backgroundWorker2.ReportProgress(0);
                        }
                        i++;

                }



private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        metroProgressBar1.Minimum = 0;
        metroProgressBar1.Maximum = progressCount;
         stock st = new stock();
        reportClass rp = (reportClass)e.UserState;
        if(!backgroundWorker2.CancellationPending)
        {
            st.stockReport.Rows.Add(rp.pName, rp.batch, rp.expr, rp.stock, rp.rate);
            metroProgressBar1.Value = e.ProgressPercentage;
            int percn = …
Run Code Online (Sandbox Code Playgroud)

c# backgroundworker

1
推荐指数
1
解决办法
385
查看次数

如果网页关闭,则让 QueueBackgroundWorkItem 完成

根据我读过的有关 QueueBackgroundWorkItem 的文献,我应该能够在后台完成一个长时间的任务而不会被 IIS 中断。

我想知道是否有可能,如果我开始一个很长的任务并在它完成之前关闭我的网站,QueueBackgroundWorkItem 不应该完成任务吗?(目前不是)

这是我的电话:

private async Task WriteTextAsync(CancellationToken cancellationToken)
{
    string filePath = printPath;
    string text;
    byte[] encodedText = Encoding.Unicode.GetBytes(text);

    for (int i = 0; i < 200; i++)
    {
        text = "Line " + i + "\r\n";
        encodedText = Encoding.Unicode.GetBytes(text);
        using (FileStream sourceStream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.None,                    bufferSize: 4096, useAsync: true))
        {
            await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
        };
        Thread.Sleep(200);
    }
}

private void QueueWorkItem()
{
    Func<CancellationToken, Task> workItem = WriteTextAsync;
    HostingEnvironment.QueueBackgroundWorkItem(workItem);
}
Run Code Online (Sandbox Code Playgroud)

编辑:我已经得到了这个工作。我修剪了它。现在在浏览器关闭后执行,大约 3-4 …

c# iis asp.net-mvc backgroundworker

1
推荐指数
1
解决办法
2603
查看次数

任务 vs 线程 vs 后台工作者的终生方法

我对这一切都有些困惑。我需要在我的应用程序中创建一个生命周期方法,它将与 asp net web 服务进行通信,并返回一些结果。只要我的应用程序在运行,这个方法就永远不会停止。

方法 1 创建任务。

 t=Task.Run(()=>ffAsync());

 async void ffAsync()
 {
    while (true)
    {
      await Task.Delay(5000);
      Console.WriteLine("Reading from server every 5 seconds");
    }
 }
Run Code Online (Sandbox Code Playgroud)

Method2 使用后台工作者

Timer t = new Timer();   
t.Interval = 5000;    
timer1.Enabled = true;  
timer1.Tick += new 
System.EventHandler(OnTimerEvent);

private void OnTimerEvent(object sender, EventArgs e) 
{
 backgroundWorker1.RunWorkerAsync();
}
Run Code Online (Sandbox Code Playgroud)

方法 3 使用线程

new Thread(() =>
{
   Thread.CurrentThread.IsBackground = true;
   while(true)
   {
      Thread.Sleep(5000);
      Console.WriteLine("Run every 5 seconds");
   }
 }).Start();
Run Code Online (Sandbox Code Playgroud)

在我的情况下哪种方法更有效?还有另一个优化问题,最好使用 task.delay(x),Thread.Sleep(x) 每 x 秒运行一次我的循环,还是创建一个计时器(如我的秒示例),它会每 x 触发一次我的事件秒?

c# multithreading task backgroundworker

1
推荐指数
1
解决办法
3824
查看次数

正确使用调用

我有一个关于 invoke 用法的一般问题。我的大多数 C# winforms 项目都有一个后台工作人员和一个 UI。很快我意识到我需要来自后台工作人员 UI 的信息,或者我需要更改我的后台工作人员的 UI。例子:

//example invoke usage to get information from UI (dateMatch = CheckBox, fromDate&toDate = Datepicker)
bool isDateMatch = false;
dateMatch.Invoke(new MethodInvoker(delegate { isDateMatch = dateMatch.Checked; }));
DateTime fromDt = new DateTime();
fromDate.Invoke(new MethodInvoker(delegate { fromDt = fromDate.Value; }));
DateTime toDt = new DateTime();
toDate.Invoke(new MethodInvoker(delegate { toDt = toDate.Value; }));
Run Code Online (Sandbox Code Playgroud)
//example invoke usage to change UI (statusTxt = TextBox, progressBar = ProgressBar)
private void changeStatus(string statusTextV, bool enableProgressBar)
{
   statusTxt.Invoke(new MethodInvoker(delegate …
Run Code Online (Sandbox Code Playgroud)

c# invoke backgroundworker winforms

1
推荐指数
1
解决办法
58
查看次数