在WPF应用程序中,我有一个有计算机的数据库访问任务,由计时器定期运行,此任务已在BackgroundWorker线程中执行.
当连接尝试失败时,我通过try_catch构造引发异常,我想更新UI线程中的状态栏文本.
是否有一些prebuild事件构建BackgroundWorker用于实现这一点,类似DoWorkEventHandler或RunWorkerCompletedEventHandler,可用于此?如果没有,怎么做得更好?
编辑(补充):
如果我想在里面处理异常RunWorkerCompletedEventHandler,使用e.Error参数,它不起作用.如果我在BackgroundWorker线程中未处理异常,应用程序挂起并且调试器指向在BackgroundWorker线程内部执行的代码字符串,说:用户代码未处理异常.
因此,在这种情况下,线程不会停止,发出信号RunWorkerCompletedEventHandler,它会因错误而停止,但整个应用程序停止工作.
我BackgroundWorker通过WebClient.DownloadString在循环内调用来使用a 来下载一些网站.我希望用户在下载内容时取消选项,所以CancelAsync每当我发现CancellationPending在循环中间打开时我都会打电话.
但是现在我注意到函数DownloadString有时会冻结,所以我决定使用DownloadStringAsync(所有这些都在创建的其他线程中BackgroundWorker).因为我不想通过在调用之后退出循环和函数来重写我的整个代码,所以在调用DownloadStringAsync之后我做了一个while循环,它什么也没做,只是检查一个变量bool Stop,我在DownloadStringCompleted事件处理程序时变为true 被叫或当用户请求取消操作时.
现在,奇怪的是它在调试版本上运行良好; 但是在第一个版本中,程序会在while循环中冻结,就好像它是主线程一样.
我不确定我是否正确地执行此操作,但是我使用了以下代码(单击button1,执行_DoWork).问题是:如何调用UI来获取textbox1和textbox2的值,因为它们不能被调用,因为它们位于不同的线程上.我应该使用调度员吗?
private void button1_Click(object sender, RoutedEventArgs e)
{
if (textBox1.Text == "")
{
MessageBox.Show("Please enter a username and password", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
}
else
{
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerAsync();
}
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("asd");
UserManagement um = new UserManagement(sm.GetServerConnectionString());
if (um.AuthUser(textBox1.Text, textBox2.Password))
{
MainWindow mw = new MainWindow();
mw.Show();
this.Close();
}
else
{
if (um.Timeout)
{
MessageBox.Show("Could not connect to server, please check your configuration", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
else
{
MessageBox.Show("Incorrect username or …Run Code Online (Sandbox Code Playgroud) 我的MultiAutoCompleteTextViewActivity中有一个小部件,其中有一个ArrayAdapter<String>由基于Web的调用结果填充的小部件.当用户在textview中键入字符时,此适配器的列表应在后台更新.实现这个的最佳方法是什么?
我已经尝试使用AsyncTask在后台下载字符串列表,但是notifyDataSetChanged()从"非原始线程"调用.而且,这似乎有点迂回.
我遇到的另一个选项是Filterable可以使用,但我没有遇到任何简单的例子(AutoComplete4似乎有点矫枉过正)如何做到这一点.如果没有例子,有人可以对我需要的演员进行广泛的概述 - 过滤,过滤等.
这也是一个好方法吗?
谢谢,
拉贾斯
我刚刚从Epio搬到了Heroku,在阅读了他们的新流程模型后,我想知道Heroku如何处理子流程.FAQ说你可以创建子进程,但没有描述这样做的任何含义.
每个子流程是否都算作新的dyno,你必须支付?如果是这样,不会使用Gunicorn也会因为它预先分配其子过程而变得昂贵吗?最后,由于Heroku隔离了它的进程,你如何与你的子进程通信?
我想做一件非常简单的事情:启动一个工作者,然后将答案返回给用户.我正在尝试使用Flask和RQ的组合.
import os
from flask import Flask, session
from somewhere import do_something
from rq import Queue
from worker import conn
app = Flask(__name__)
app.debug = True
app.secret_key = '....'
q = Queue(connection=conn)
@app.route('/make/')
def make():
job = q.enqueue(do_something, 'argument')
session['job'] = job
return 'Done'
@app.route('/get/')
def get():
try:
session['job'].refresh()
out = str(session['job'].result)
except:
out = 'No result yet'
return out
Run Code Online (Sandbox Code Playgroud)
这个非常简单的例子中的想法是人们去/ make /并开始工作.经过一段时间后,可以进入/ get /并将工作人员的结果打印出来.
然而,一行导致问题:
session['job'] = job
Run Code Online (Sandbox Code Playgroud)
似乎这项工作无法被腌制,这显然是由Flaks会议使用的.我收到错误:
...
10:52:16 web.1 | File "/Users/julius/twitter-sentiment/venv/lib/python2.7/site-packages/flask/app.py", line 804, in save_session …Run Code Online (Sandbox Code Playgroud) 我需要创建队列并将其与BackgroundWorker一起使用.所以我可以添加操作,当接下来完成一个操作时就是在后台启动.我通过谷歌找到了这个代码:
public class QueuedBackgroundWorker<T>
{
public void QueueWorkItem(
Queue queue,
T inputArgument,
Func<T> doWork,
Action workerCompleted)
{
if (queue == null) throw new ArgumentNullException("queue");
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = false;
bw.WorkerSupportsCancellation = false;
bw.DoWork += (sender, args) =>
{
if (doWork != null)
{
args.Result = doWork(new DoWorkArgument<T>((T)args.Argument));
}
};
bw.RunWorkerCompleted += (sender, args) =>
{
if (workerCompleted != null)
{
workerCompleted(new WorkerResult<T>((T)args.Result, args.Error));
}
queue.Dequeue();
if (queue.Count > 0)
{
QueueItem<T> nextItem = queue.Peek() as QueueItem<T>;
nextItem.BackgroundWorker.RunWorkerAsync(nextItem.Argument); …Run Code Online (Sandbox Code Playgroud) 我目前正在编写一个简单的WPF 3.5应用程序,它利用SharePoint COM调用SharePoint站点并生成组和用户信息.由于此过程需要一段时间,因此我希望在生成组时显示ProgressBar.期望的过程如下:
我遇到的问题是UI永远不会更新.ProgressBar或ListView都不做任何更改.如果有人有任何想法来帮助下面的代码,将不胜感激.
private void GetGroupsAndUsersButton_Click(object sender, RoutedEventArgs e)
{
siteUrl = "";
if (SiteURLTextBox.Text.Length > 0)
{
FetchDataProgressBar.IsIndeterminate = true;
mWorker = new BackgroundWorker();
mWorker.DoWork += new DoWorkEventHandler(worker_DoWork);
mWorker.WorkerSupportsCancellation = true;
mWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
mWorker.RunWorkerAsync();
}
else
{
System.Windows.MessageBox.Show("Please enter a URL for the SharePoint site you wish to retrieve data");
}
}
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
siteUrl = SiteURLTextBox.Text;
GroupListView.ItemsSource = null;
try
{
using (SPSite site = new …Run Code Online (Sandbox Code Playgroud) 因此,这就是我目前使用后台工作程序将大量内容保存到文件中的方式,同时向用户显示进度条并防止在保存过程中对UI进行任何更改.我想我已经捕获了基本功能.模态ProgressWindow显示进度条而不是其他.async-await如果必须的话,我将如何将其更改为模式?
private ProgressForm ProgressWindow { get; set; }
/// <summary>On clicking save button, save stuff to file</summary>
void SaveButtonClick(object sender, EventArgs e)
{
if (SaveFileDialog.ShowDialog() == DialogResult.OK)
{
if (!BackgroundWorker.IsBusy)
{
BackgroundWorker.RunWorkerAsync(SaveFileDialog.FileName);
ProgressWindow= new ProgressForm();
ProgressWindow.SetPercentageDone(0);
ProgressWindow.ShowDialog(this);
}
}
}
/// <summary>Background worker task to save stuff to file</summary>
void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
{
string path= e.Argument as string;
// open file
for (int i=0; i < 100; i++)
{
// get some stuff from …Run Code Online (Sandbox Code Playgroud) 我通常在C#中编写Windows服务,但我在F#中使用它.对于像这样的轮询服务,我通常使用我写的类,类似于BackgroundWorker.它产生一个后台线程并定期触发OnWork方法.(完整代码在这里[github].)
在F#中有另一种,或许更好或更惯用的方法吗?它可能是编写轮询后台工作者类或内置替代方法的更好方法.
根据乔尔的建议,这就是我提出的问题.
module Async =
open System.Diagnostics
let poll interval work =
let sw = Stopwatch()
let rec loop() =
async {
sw.Restart()
work()
sw.Stop()
let elapsed = int sw.ElapsedMilliseconds
if elapsed < interval then
do! Async.Sleep(interval - elapsed)
return! loop()
}
loop()
//Example
open System.Threading
let cts = new CancellationTokenSource()
Async.Start(Async.poll 2000 (fun () -> printfn "%A" DateTime.Now), cts.Token)
Thread.Sleep(TimeSpan.FromSeconds(10.0))
cts.Cancel()
Run Code Online (Sandbox Code Playgroud)
该服务使用poll:
type MyService() =
inherit System.ServiceProcess.ServiceBase()
let …Run Code Online (Sandbox Code Playgroud) backgroundworker ×10
c# ×6
wpf ×4
flask ×2
python ×2
.net ×1
android ×1
async-await ×1
cancellation ×1
f# ×1
generics ×1
heroku ×1
queue ×1
redis ×1
session ×1
sharepoint ×1
web ×1
winforms ×1