我们有一个 C# 应用程序,它连接到 FTP 服务器、下载一些文件、断开连接,并在一段时间后(由用户通过 UI 选择)重新连接并重复该过程。我们使用BackgroundWorker 实现了这一点,但我们注意到,运行较长时间后,程序停止在UI 和日志文件中记录其操作。那时,没有文件可供它下载,因此我们上传了一些文件,它恢复了活动,就好像什么也没发生一样。
问题是普通用户无法知道程序仍在运行,因此我们决定使用我们自己的线程来实现它。我们做了一个更简单的程序,以排除任何其他问题,这个程序只连接到 FTP 并断开连接。它像BackgroundWorker 一样停止显示消息(2 小时后一次,22 小时后一次,没有我们能找到的任何模式,并且在一台没有执行任何其他操作的计算机上)。
DoFTPWork += new DoFTPWorkDelegate(WriteFTPMessage);
FTPWorkThread = new Thread(new ParameterizedThreadStart(Process));
//seData is the FTP login info
FTPWorkThread.Start(seData);
Run Code Online (Sandbox Code Playgroud)
FTP方法是:
private void Process(object seData1)
{
seData = (SEData)seData1;
while (!stopped)
{
try
{
ftp = null;
ftp = new FTP_Client();
if (ftp.IsConnected)
{
logMessages += DateTime.Now + "\t" + "info" + "\t" + "Ftp disconnected from " + seData.host + "\r\n";
ftp.Disconnect();
}
ftp.Connect(seData.host, 21);
ftp.Authenticate(seData.userName, seData.password);
logMessages …Run Code Online (Sandbox Code Playgroud) 我正在运行一个BackgroundWorker 线程来执行一项耗时的任务。耗时的任务在另一个类中。我需要将在BackgroundWorker 上运行的这个单独的类所取得的进度传递回Main Form1 类。我不知道如何处理这个问题。请提供建议。先感谢您。
**// Main Form1 UI Class**
public void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
//e.Argument always contains whatever was sent to the background worker
// in RunWorkerAsync. We can simply cast it to its original type.
DataSet ds = e.Argument as DataSet;
this.createje.ProcessData(this.ds);
}
private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Minimum = 0;
this.progressBar1.Maximum = CreateJE.max;
this.progressBar1.Value = e.Recno;
}
**//Other Class called CreateJE**
public void ProcessData(DataSet ds)
{
//Do time consuming task...
for (int i …Run Code Online (Sandbox Code Playgroud) Msdn 文档对 WriteVerbose 方法说:
“只能从 BeginProcessing、ProcessRecord 和 EndProcessing 方法的实现中调用此方法,并且只能从该线程调用。如果从这些实现外部或另一个线程调用此方法,则会引发 InvalidOperationException 异常。”
但是在我的测试代码中,我能够在三个标准方法之外调用该方法。但是当从不同的线程调用该方法时,我得到了一个异常。
我相信这里的大多数人在实现自定义 cmdlet 时都需要多线程支持。
我正在使用后台工作者来完成简单的多线程。在继续之前,我在 ProcessRecord 函数中等待 doWork 事件完成。现在我想使用来自 doWork 的 writeverbose 向用户报告进度,但由于它是一个不同的线程,我不能这样做。
我已经尝试使用带有 AutoResetEvent 的并发队列来实现这一点,但是有没有更好的方法以更简单的方式解决这个问题?
我有一个功能可以在网络上抓取数据并计算搜索分数。但是,这可能需要一段时间,有时网页会在完成执行之前超时。
因此,我创建了一个单独的线程来执行该函数并loading.html告诉客户端仍在收集数据。一旦函数在线程中结束,我如何重新加载网页以显示output.html显示分数。
这是我迄今为止所拥有的一个更简单的版本:
from flask import Flask
from flask import render_template
from threading import Thread
app = Flask(__name__)
@app.route("/")
def init():
return render_template('index.html')
@app.route("/", methods=['POST'])
def load():
th = Thread(target=something, args=())
th.start()
return render_template('loading.html')
def something():
#do some calculation and return the needed value
if __name__ == "__main__":
app.run()
Run Code Online (Sandbox Code Playgroud)
如何 在线程完成render_template('output.html', x=score) 后将我的应用程序路由到一次?something()th
我试图避免像 redis 这样的任务队列,因为我想在网络上部署这个应用程序,我不想产生费用(这更像是一种实验和爱好)。
详细的代码答案会很有帮助,因为我是烧瓶和多线程的新手
我正在使用后台工作者进行 BLE RSSI 级别测试。
我的问题是 RunWorkerCompleted 事件在 DoWork 完成操作之前立即触发。
大多数 DoWork 事件操作是创建广告观察程序并等待来自蓝牙低功耗设备的信号。信号级别将从主线程更新,结果的处理将在后台工作人员上进行。
这是我致电后台工作人员时的情况:
...
worker = new BackgroundWorker();
worker.DoWork += callTestBLE;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.RunWorkerAsync(RSSI_Label);
}
Run Code Online (Sandbox Code Playgroud)
事件处理程序:
private async void callTestBLE(object sender, DoWorkEventArgs e)
{
BluetoothLEAdvertisementWatcher watcher1 ;
BluetoothLEAdvertisementFilter advertisementFilter1;
int rssiRetries1 = RSSIRETRIES;
RssiValue = "";
advertisementFilter1 = new BluetoothLEAdvertisementFilter();
try
{
advertisementFilter1.Advertisement.LocalName = myUswm.getAdvetrismentName();
checkRSSI = true;
}
catch (Exception) { checkRSSI = false; return; }
watcher1 = new BluetoothLEAdvertisementWatcher(advertisementFilter);
watcher1.ScanningMode = BluetoothLEScanningMode.Active;
watcher1.Received += OnAdvertisementReceived;
// Wait …Run Code Online (Sandbox Code Playgroud) 我想同步我的文件夹,所以我有 10 个 Filesystemwatcher 和 4 个后台工作者。这个想法是,一个观察者可以调用 4 个工作人员中的每一个,但我希望观察者选择一个活跃且自由的工作人员,其他人不应该被触发。
实验:1 名工人被解雇,2-4 名工人没有被解雇。
我在这里做错了什么?
这是我的代码
private void watcher1_OnChanged(object source, FileSystemEventArgs e)
{
// File Name
string file = e.FullPath;
// refresh App.Config
ConfigurationManager.RefreshSection("appSettings");
// Check Worker Active
bool worker1Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker1Active"]);
bool worker2Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker2Active"]);
bool worker3Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker3Active"]);
bool worker4Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker4Active"]);
// Watcher Nummer
string watcherNr = "Watcher 1";
// Arguments to call worker
List<object> arguments = new List<object>();
arguments.Add(file);
arguments.Add(watcher1_destinationPath);
arguments.Add(watcher1_sourcePath);
arguments.Add(watcherNr);
bool success = false;
while (!success …Run Code Online (Sandbox Code Playgroud) 让我们假设我正在使用后台工作人员并且我有以下方法:
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
finalData = MyWork(sender as BackgroundWorker, e);
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
int i = e.ProgressPercentage; // Missused for i
Debug.Print("BW Progress Changed Begin, i: " + i + ", ThreadId: " + Thread.CurrentThread.ManagedThreadId);
// I use this to update a table and an XY-Plot, so that the user can see the progess.
UpdateGUI(e.UserState as MyData);
Debug.Print("BW Progress Changed End, i: " + i + ", ThreadId: " + Thread.CurrentThread.ManagedThreadId); …Run Code Online (Sandbox Code Playgroud) c# backgroundworker race-condition winforms measurement-studio
我需要一个 IHostedService 或“工作服务”,但我遇到了一个有趣的难题,那就是垃圾收集器没有在“适当”的时间运行。相反,它只是不收集任何资源,导致应用程序的内存使用量增加(在调试期间,根本没有发生 GC)。
我已经做了所有能想到的事情,包括让所有任务返回一些值,以及尽可能使用 using 语句。还使用依赖注入抽象了几个层(以确保有多个位置应该与运行时通信,表明它适合运行垃圾收集。
我唯一的“解决方案”(不是解决方案)是手动运行 GC.Collect();
namespace Worker
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation($"Worker running at: {DateTime.Now}");
var files = Directory.EnumerateFiles(@"C:\\repos\");
var date = files.Select(f => File.ReadAllBytesAsync(f));
GC.Collect();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果是,我的代码在不手动触发 GC 的情况下会膨胀到最大可用内存,但是,使用手动 GC 可以运行数小时,而资源使用情况不会发生明显变化
解决方案 使用本文中提到的设置:https://dotnet.github.io/orleans/1.5/Documentation/Deployment-and-Operations/Configuration-Guide/Configuring-.NET-Garbage-Collection.html(已弃用)
更新的链接:https://learn.microsoft.com/en-us/dotnet/core/run-time-config/garbage-collector
c# resources garbage-collection backgroundworker asp.net-core-hosted-services
有点远,但是当没有HttpContext.Current可用时,ASP.NET中有一种方法可以动态获取网站的URL(http://www.example.com).
没有HttpContext,因为代码在后台线程*中运行(但在ASP.NET AppDomain下).我有一个后台进程,将每天晚上邮件出去,需要包括网络地址,但我不想因为部署和测试的硬编码(它改变的http://本地主机:12345到HTTP:/ /testing.example.com然后到http://www.example.com获取实时网站).
*请不要建议Windows服务,我知道这些,但托管限制阻止我这样做.
我正在编写一个WPF应用程序(新技术,主要是我一直在WinForms编写).我的目标是让UI响应整个时间,并且我已经读过它可以使用Threading/BackgroundWorker获得.我认为我应该使用后台工作者来处理耗时的方法.但我计划使用方法*m_AddLog(string logText)*,它应该将文本附加到文本框.我希望从主UI线程以及后台工作者调用此方法,因此消息将在后台处理时立即发送,而不是等待后台任务结束.你能不能请建议如何正确地写这些方法,让UI完全响应,因为我不太了解代表,调用,后台工作者等等?
backgroundworker ×10
c# ×7
asp.net ×1
asp.net-core-hosted-services ×1
cmdlets ×1
flask ×1
heroku ×1
httpcontext ×1
powershell ×1
python ×1
resources ×1
textbox ×1
url ×1
winforms ×1
wpf ×1