灵感来自我自己在多线程Winforms应用程序方面的经验,以及诸如此类的问题
我想出了一个非常简单的模式,我想验证它的健全性.
基本上我正在创建(并在整个应用程序的生命周期内运行)BGW,其唯一目的是同步调用请求.考虑:
public MainForm()
{
InitializeComponent();
InitInvocationSyncWorker();
}
private void InitInvocationSyncWorker()
{
InvocationSync_Worker.RunWorkerAsync();
}
private void InvocationSync_Worker_DoWork(object sender, DoWorkEventArgs e)
{
Thread.Sleep(Timeout.Infinite);
}
void InvokeViaSyncWorker(Action guiAction)
{
InvocationSync_Worker.ReportProgress(0, guiAction);
}
private void InvocationSync_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (IsDisposed) return; //we're in the GUI thread now, so no race condition right?
var action = (Action) e.UserState;
action();
}
public void SomeMethodCalledFromAnyThread() //Sample usage
{
InvokeViaSyncWorker(() => MyTextBox.Text = "Hello from another thread!"));
}
Run Code Online (Sandbox Code Playgroud)
当然,这不是最经济的方法(让线程保持活力),但如果它有效并且我没有错过任何东西,那肯定是我见过的最简单的.
反馈非常感谢!
我正在使用VB.NET 2005进行编程.我使用a BackgroundWorker来加载大型列表或文本文件并进行处理.
是否可以使用相同的后台工作程序来处理其他内容,即处理已加载的文本文件?
有点像
Dim bwkMain as New BackgroundWorker()
Run Code Online (Sandbox Code Playgroud)
如果可能,我如何以与我已经为第一个实现的相同的形式实现它?
编辑
问题是:在完成一项任务后,是否可以将相同的BackgroundWorker用于其他任务?
我有10个超过100Mb的列表,每个都有电子邮件,我想尽可能快地使用多线程处理它们而不将它们加载到内存中(比如逐行读取或读取小块)
我创建了一个函数,它根据正则表达式删除无效的函数,另一个函数根据每个域将它们组织到其他列表.
我设法使用一个线程:while(reader.Peek()!= -1),但它太长了.
如何在并行处理列表时使用多线程(大约100 - 200)和背景工作者或某些东西来使用表单?
我是csharp的新手:P
我有一个后台工作者的应用程序.在doWork方法中,我执行html Web请求.如果此请求失败(例如错误404),我想在完成之前退出线程.所以在我的捕获中我添加了这段代码
worker.CancelAsync();
if (worker.CancellationPending)
{
e.Cancel = true;
}
Run Code Online (Sandbox Code Playgroud)
问题是线程没有停止,但它创建了一个新的html Web请求.
一些代码:
try
{
var request = (HttpWebRequest)WebRequest.Create(url1);
request.Timeout = 5000;
request.UserAgent = @"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5";
var document = new HtmlAgilityPack.HtmlDocument();
try
{
using (var responseStream = request.GetResponse().GetResponseStream())
{
document.Load(responseStream, Encoding.UTF8);
//some lines of code to parse html
}
catch (WebException we){
worker.CancelAsync();
if (worker.CancellationPending)
{
e.Cancel = true;
return;
}
}
catch (Exception) { }
Run Code Online (Sandbox Code Playgroud)
这是我的工作方法......
我是C#的新手,我正试图围绕面向对象的编程.这就是我想要完成的事情:
我有一个带有Form1的Windows窗体应用程序和一个名为connect(相同的命名空间)的单独类.
我知道在执行大量代码时使用后台工作人员是一种好习惯(以免冻结UI).所以我在Form1中创建了一个后台工作程序和一个progresschanged句柄.我试图找到如何在单独的连接类中触发progresschange.在Form1的progresschange块中,我有一个case/switch,用于确定屏幕上显示的文本.
解决这个问题的最佳方法是什么?我可以把背景工作者传给其他班级吗?
我需要一个需要每隔x秒永久运行的操作,并且实现这一点:
protected void Application_Start()
{
InitialieOnce.Initialize();
}
public static class InitialieOnce
{
private static bool initialized = false;
public static void Initialize()
{
if (initialized == false)
{
initialized = true;
Thread t = new Thread(x => CheckStatus());
t.IsBackground = true;
t.Start();
}
}
private static void CheckStatus()
{
//My script goes here.
Thread.Sleep(8000);
CheckStatus();
}
}
Run Code Online (Sandbox Code Playgroud)
一段时间后(大约5分钟)我收到此错误:"mscorlib.dll中发生了'System.StackOverflowException'类型的未处理异常"
这个错误可以与我如何制作无限循环有关吗?
如果是,是否有更好的方法来实现这一点,我可以解决它,或者这个代码是否正常?
我想实时显示(例如每1秒更新一次)某些温度到我的程序界面.
为此,我相信我将需要在后台工作程序中运行一些代码,以便主程序不会被阻止.我的问题是,是否可以设置TextBlock背景工作者的文本,如果可以,则如何设置.
这是基本的想法:
backgroundworker
{
while(true)
{
//reading and updating temperatures
//.....
}
}
Run Code Online (Sandbox Code Playgroud) 我今天做了一个小测试,以了解有关BackgroundWorker的更多信息.
在我看来,它不适用于asychronuos模式.首先它做了Do1和下一个Do2.Do2更短,Do1需要更多时间,但是程序等待Do1完成并且下一次启动Do2.我对吗?谢谢!
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Transactions;
namespace ConsoleApplication16
{
public interface I
{
void UstawWiek(string w);
void PokazWiek();
}
class rrr
{
public delegate void MojDelegat();
public static void Do1(object sender, DoWorkEventArgs e)
{
System.Threading.Thread.Sleep(4000);
Console.WriteLine("Do1");
}
public static void Do2(object sender, DoWorkEventArgs e)
{
System.Threading.Thread.Sleep(1000);
Console.WriteLine("Do2");
}
static void Main(string[] args)
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(Do1);
bw.DoWork += …Run Code Online (Sandbox Code Playgroud) 有人可以解释为什么Thread.Sleep从BackgroundWorker块执行调用它.调用应该导致委托在UI线程上执行,后台线程应该继续执行.但这不会发生 - 为什么?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
BackgroundWorker bgrw = new BackgroundWorker();
bgrw.DoWork += new DoWorkEventHandler(bgrw_DoWork);
bgrw.RunWorkerAsync();
}
void bgrw_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine(DateTime.Now);
this.Invoke(new Action(() => { Thread.Sleep(2000); })); //should be executed on the UI thread
Console.WriteLine(DateTime.Now); // This line is executed after 2 seconds
}
}
Run Code Online (Sandbox Code Playgroud) 我是后台流程的新手,所以如果我做错了假设,请随时指出。
我正在尝试编写一个脚本,用于将导入数据从大型CSV文件导入Neo4j db(将其视为数据流,无休止地)。csv文件仅包含两列-user_a_id和user_b_id,它们映射有向关系。需要考虑的几件事:
我当前的解决方案:我正在使用sidekiq,并且有一个工作人员批量读取文件,并分派工作人员在数据库中创建边。
我遇到的问题:
可能的解决方案:建立一个同步队列,并且只有一个工作线程来执行写操作(似乎sidekiq或resque都没有该选项)。这可能非常慢,因为只有一个线程在工作。
或者,我可以编写自己的实现,该实现创建一个工作程序以根据user_id(每个队列一个唯一的ID)构建多个作业队列,并使用Redis进行存储。然后,为每个队列分配一个工作线程以写入数据库。设置最大队列数,这样我就不会用完内存,并在队列耗尽所有作业后将其删除(如果以后会看到相同的user_id,请重新构建它)。-虽然听起来并不简单,所以我更喜欢在使用之前使用现有的库。
我的问题是-是否可以使用现有的宝石?处理此问题的良好做法是什么?
backgroundworker ×10
c# ×8
.net ×4
asp.net-mvc ×1
asynchronous ×1
class ×1
invoke ×1
large-files ×1
neo4j ×1
ruby ×1
task ×1
vb.net ×1
winforms ×1
wpf ×1