标签: backgroundworker

将 ASPNET API 添加到现有 Worker Service 项目

我目前有一个 dotnet 5.0 Worker Service 项目,该项目托管一个后台服务,该服务定期执行业务线流程。我设法通过在CreateHostBuilder方法内设置主机来摸索,并且这一切都作为 docker 容器内的可执行文件运行良好。

但是,我现在想添加一个 HTTP api / ui,以便我可以公开一个“健康”端点和一些漂亮的网页,这些网页访问与后台服务相同的进程内内存,以执行诸如显示 in 的内容之类的操作。 -内存缓存、逐出缓存条目、手动触发业务流程的运行等,我完全迷失了。

我想我只是以某种方式在绑定ConfigureServices到我指定的端口上的 ASPNET razor 项目中定义的类的方法中配置一个额外的托管服务,但经过几次尝试后,我有点困惑如何开始解决这个问题,更不用说让它真正发挥作用:-(。

具体来说,我有一个如下所示的 C# 项目:

我的Worker.csproj

<Project Sdk="Microsoft.NET.Sdk.Worker">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
    <PackageReference Include="Serilog.Extensions.Hosting" Version="4.0.0-dev-00051" />
    <PackageReference Include="Serilog.Formatting.Compact" Version="1.1.1-dev-00940" />
    <PackageReference Include="Serilog.Sinks.Console" Version="4.0.0-dev-00839" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\MyAppCode\MyAppCode.csproj" />
  </ItemGroup>

</Project>
Run Code Online (Sandbox Code Playgroud)

和一个如下所示的Program.cs :

        public static void Main(string[] args)
        {

            Program.InitSerilog();
            Program.CreateHostBuilder(args).Build().Run();

        }

        public static void InitSerilog()
        {
            ... do …
Run Code Online (Sandbox Code Playgroud)

c# backgroundworker .net-core asp.net-core

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

如何访问Dispatcher中的WPF对象?

我正在使用MVVM模式开发WPF应用程序.

该应用程序从服务器加载验证码图像,并在准备好时将其分配给WPF表单上的图像.我正在使用BackgroundWorker为我做线程,如下所示:

加载Window时,会调用以下内容:

BackgroundWorker _bgWorker = new BackgroundWorker();

_bgWorker.DoWork += GetCaptchaImage;
_bgWorker.RunWorkerAsync();
Run Code Online (Sandbox Code Playgroud)

GetCaptchaImage函数非常简单,在另一个线程中加载图像:

BitmapSource _tempBitmap = GetCaptchaFromServer();
Run Code Online (Sandbox Code Playgroud)

我需要知道如何调用Dispatcher将此ImageSource分配给我的Window的图像源,目前我在加载_tempBitmap之后调用调度程序,如下所示:

Application.Current.Dispatcher.Invoke(
new Action(() => CaptchaBitmap = _tempBitmap));
Run Code Online (Sandbox Code Playgroud)

CaptchaBitmap数据绑定到我的图像源.

但是,当我这样做时,抛出InvalidOperationException,并且对_tempBitmap的任何引用都会在GUI线程中返回错误.我知道它是因为我在调度程序GUI线程中访问它,当它在BackgroundWorker线程中创建时,但我该如何解决它?

非常感谢帮助!:)

wpf multithreading mvvm backgroundworker

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

当我的后台进程正在进行时,如何向列表框中添加值?

我正在创建一个应用程序.我正在扫描驱动器的文件以搜索特定模式我的进度条正在更新,最后所有文件名都列在列表框中.我想要立即列出所有这些文件一旦发现它们包含图案.

我正在使用BackgroundWorker

c# backgroundworker

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

C#:如何在BackgroundWorker进度报告回调中解决"Collection was modified"?

我已经使用了BackgroundWorkers了,但我以前从未遇到过这个问题.我的程序分析逻辑分析仪的输出,产生数据包,其中有数千个.为了防止更新延迟更新我的表单中的ListView(我之前报告了每个发现的,并且表单完全没有响应)我正在收集通用列表(List <Packet>)中的BackgroundWorker内的数据包和然后报告当找到n量(当前为250),或者发生异常时,或者当它完成时.

当我在List <Packet>上进行迭代时,问题发生在我的回调中,我得到一个InvalidOperationException,其中包含"Collection was modified"错误.我没有触及foreach中的集合(我正在添加到另一个集合中,但我认为没有理由可以修改我正在迭代的集合 - 再加上评论它不能解决问题.)我是甚至尝试锁定e.UserState,将e.UserState存储到本地作用域List <Packet>并锁定,似乎没有任何作用.

这是我的回调方法的代码:

void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar.Value = e.ProgressPercentage;
    packetsListView.SuspendLayout();
    lock ((List<Packet>)e.UserState)
    {
        foreach (Packet packet in (List<Packet>)e.UserState)
        {
            packets.Add(packet);
            ListViewItem item = new ListViewItem(string.Format("{0}ns", Math.Round(packet.StartSampleNumber * 41.666667)));
            item.Tag = packet;
            item.SubItems.Add(new ListViewItem.ListViewSubItem(item, packet.Description));
            packetsListView.Items.Add(item);
        }
    }
    packetsListView.ResumeLayout();

    statusLabel.Text = string.Format("Analyzing...found {0} {1}", packetsListView.Items.Count, packetsListView.Items.Count == 1 ? "packet" : "packets");
}
Run Code Online (Sandbox Code Playgroud)

c# collections multithreading generic-list backgroundworker

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

在两个线程之间进行通信

我有这样的感觉.它给了我错误.我删除了所有不需要的代码部分.它给了我这个错误

The calling thread cannot access this object because a different thread owns it.
Run Code Online (Sandbox Code Playgroud)
 public partial class MainWindow : Window
{
    BackgroundWorker worker;
    Grafik MainGrafik;

    double ProgressBar
    {
        set { this.progressBarMain.Value = value; }
    }

    public MainWindow()
    {
        InitializeComponent();
        worker = new BackgroundWorker();
        worker.DoWork += new DoWorkEventHandler(worker_DoWork);

        MainGrafik = new Grafik();
        MainGrafik.ProgressUpdate += 
            new Grafik.ProgressUpdateDelegate(MainGrafik_ProgressUpdate);

        worker.RunWorkerAsync();
    }

    void MainGrafik_ProgressUpdate(double progress)
    {
        ProgressBar = progress;
    }


    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        while(true)
        {
            MainGrafik.Refresh();
            Thread.Sleep(2000);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
class Grafik …
Run Code Online (Sandbox Code Playgroud)

.net c# events multithreading backgroundworker

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

报告多个百分比的背景工作者

我希望我的后台工作人员报告单个任务和总进度的进度.有什么建议我如何得到多个值到backgroundworker_ProgressChanged?

谢谢

c# backgroundworker winforms

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

Dispatcher.Invoke循环冻结UI

我有日志拖尾应用程序,它在不定式循环中执行后台工作程序线程并检查某些TXT文件中的最新条目.一旦找到新条目,我使用Dispatcher.Invoke更新屏幕上的TextBox,并将最新条目添加到文本文件中.

问题是,如果源文本文件每毫秒不断更新,用户界面就会冻结,因为Dispatcher.Invoke经常更新文本框.

不知道是否有任何解决方法.我可以从文本文件中获取更大的块但不想破坏日志拖尾的实时体验,也不想延迟通过UI线程将行写入TextBox,因为这会使我的应用程序与实际数据不同步源文本文件.

这是后台工作者的DoWork方法

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
  reader = new StreamReader(new FileStream(file.File, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
  lastMaxOffset = reader.BaseStream.Length;

  while (true)
  {
    if (worker.CancellationPending)
    {
      e.Cancel = true;
      break;
    }                

    if (reader.BaseStream.Length == lastMaxOffset)
      continue;

    reader.BaseStream.Seek(lastMaxOffset, SeekOrigin.Begin);

    string line = "";
    while ((line = reader.ReadLine()) != null)

    this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)(() =>
    {
      textLog.Text += "\r" + line;
      scrollViewer.ScrollToBottom();
    })); 

    lastMaxOffset = reader.BaseStream.Position;        
  }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,UI线程只是简单地将文本附加到TextBox,并且当它经常发生接口冻结时

wpf textbox dispatcher backgroundworker

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

使用BackgroundWorker的ObjectContext.SaveChanges

我有ObjectContext.SaveChanges方法的问题:

  public void Save(Action<object, object> action)
    {
        EventAggregator.GetEvent<EntityServiceRequestingEvent>().Publish(true);
        var bw = new BackgroundWorker();
        var saved = false;
        bw.DoWork += (o, ee) =>
                         {
                             ProgramStatusService.Status = Resources.DatabaseSavingMessage;


                             if (!CanSave())
                             {
                                 throw new InvalidOperationException(
                                     "You must not call Save when CanSave returns false.");
                             }
                             try
                             {
                                 lock (Context)
                                 {
                                     Context.SaveChanges();
                                     saved = true;    
                                 }
                             }
                             catch (ValidationException e)
                             {
                                 MessageService.ShowError(null, string.Format(CultureInfo.CurrentCulture,
                                                                              Resources.SaveErrorInvalidEntities,
                                                                              e.Message));
                             }
                             catch (UpdateException e)
                             {
                                 var innerException = e.InnerException as SqlException;
                                 if (innerException != null && innerException.Number == 2601) …
Run Code Online (Sandbox Code Playgroud)

wpf entity-framework backgroundworker

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

如何调用组件

在我的应用程序中我使用backgroundWorker,在一些TextBox中设置文本,我首先需要调用TextBox.

首先我使用:

            if (someTextBox.InvokeRequired)
            {
                someTextBox.Invoke((MethodInvoker)delegate
                {
                    someTextBox.Text = "some_text";
                });
            }
            else
            {
                    someTextBox.Text = "some_text";
            }
Run Code Online (Sandbox Code Playgroud)

这个方法对我很好,但因为我有多个TextBox-es我写道:

    private void invComp(TextBox txtBox, String str)
    {
        if (txtBox.InvokeRequired)
        {
            txtBox.Invoke((MethodInvoker)delegate
            {
                txtBox.Text = str;
            });
        }
        else
        {
            txtBox.Text = str;
        }
    }
Run Code Online (Sandbox Code Playgroud)

最好以这种方式调用它?(invComp(someTextBox,"some_text");或者我可能有第三种,更好的方式?

我调用了一些按钮,我想在按钮上写这样的东西,如果这样可以吗?

TNX

c# invoke backgroundworker

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

C#SetPropertyThreadSafe vs调用线程安全调用

从另一个线程更新UI这两种方法中哪一种更好?(对我来说,他们都工作,但哪个更安全?)我更喜欢SetPropertyThreadSafe方法,因为它需要更少的代码.

1.

label1.SetPropertyThreadSafe(() => this.label1.Text, "New Value");
Run Code Online (Sandbox Code Playgroud)

2.

if (label1.InvokeRequired)
{
   label1.Invoke(new MethodInvoker(delegate {
   label1.Text="New Value"; }));
}            
Run Code Online (Sandbox Code Playgroud)

.net c# multithreading invoke backgroundworker

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