我试图在onUtteranceCompleted()中从非UI线程创建一个对话框:
runOnUiThread(
new Thread(new Runnable() {
public void run() { MyDialog.Prompt(this); }
}).start());
Run Code Online (Sandbox Code Playgroud)
Prompt()是MyDialog类的一个简单的静态方法:
static public void Prompt(Activity activity) {
MyDialog myDialog = new MyDialog();
myDialog.showAlert("Alert", activity);
}
Run Code Online (Sandbox Code Playgroud)
问题是,我正在尝试做两件错误:
通过将对话框创建推迟到UI线程,我想要的只是"做对了",但似乎我遗漏了一些基本的东西.
我缺少什么,如何完成我想要实现的看似简单的任务?
处理计算量大的任务的常用 VB 方法是将其放入后台工作线程,而主线程继续处理 UI。
不管出于什么原因,我需要以相反的方式执行此操作:主线程执行繁重的工作,后台线程更新 UI。
这是我到目前为止所拥有的。唯一的问题是,虽然 UI 窗口 (Form1) 确实被重绘,但您无法与其交互,甚至无法移动它或调整其大小(鼠标光标变成沙漏状并且无法单击)。
Public Class ProgressDisplay
Private trd As Thread
Public Sub New()
trd = New Thread(AddressOf threadtask)
trd.Start()
End Sub
Private Sub threadtask()
Dim f1 As Form1
f1 = New Form1
f1.Show()
Do
f1.Update()
Thread.Sleep(100)
Loop
End Sub
End Class
Run Code Online (Sandbox Code Playgroud)
编辑:理想情况下,我需要向客户端呈现这样的界面
Public Class ProgressDisplay
Public Sub New()
Public Sub Update(byval progress as int)
End Class
Run Code Online (Sandbox Code Playgroud)
客户端将像这样调用它(实际上是在 COM 上的非托管 c++ 中,但你明白了):
Dim prog = new ProgressDisplay()
DoLotsOfWork(addressof prog.update) ' DoLotsOfWork method takes …Run Code Online (Sandbox Code Playgroud) vb.net multithreading message-pump ui-thread applicationcontext
我有一个使用BroadcastReceiver的警报,但我对线程有点困惑.我想让它在一个单独的线程上运行,所以它不会导致对其他任何事情没有反应,但是当查看Android Docs时,我仍然不知道是否只有一个主线程,或者每个应用程序都有它的自己的主线程.
例如,如果我的应用程序没有运行,如果每个应用程序运行自己的主线程,那么在BroadcastReceiver中运行单独线程的意义是什么,这意味着我不会影响用户的其他进程.由于我没有运行,不管它做什么都不会伤害.但相反,如果所有应用程序都有一个主线程,那么我需要将操作移动到一个单独的线程.我希望我不是在问一个愚蠢的问题.我只想彻底了解它.提前致谢.
我写了一个小应用程序,它每3秒更改一次应用程序背景.我使用Handler和Runnable对象来实现这一点.它工作正常.这是我的代码:
public class MainActivity extends Activity {
private RelativeLayout backgroundLayout;
private int count;
private Handler hand = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button clickMe = (Button) findViewById(R.id.btn);
backgroundLayout = (RelativeLayout) findViewById(R.id.background);
clickMe.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
count = 0;
hand.postDelayed(changeBGThread, 3000);
}
});
}
private Runnable changeBGThread = new Runnable() {
@Override
public void run() {
if(count == 3){
count = 0;
}
switch (count) {
case 0:
backgroundLayout.setBackgroundColor(getResources().getColor(android.R.color.black));
count++;
break; …Run Code Online (Sandbox Code Playgroud) 我googleMap从一个ArrayList对象中添加了标记.大约有250个标记; 我甚至必须将它们转换为位图来自定义它们.这是一项资源密集型任务.但它严重阻止了我的UI线程.
我是这样做的:
final HashMap<Marker, NearLocation> markerIdMap = new HashMap<Marker, NearLocation>();
for (final NearLocation result : MainActivity.nearLocationList) {
// Do all the hard work here
}
Run Code Online (Sandbox Code Playgroud)
在地图加载后,如何以某种方式动态地执行此操作,并在生成它们时填充它们?我不确定我是否可以通过在后台完成一些工作来做到这一点,然后当标记完成时将其移动到UI线程进行添加.
我知道如何用一个单独的方式做到这一点AsyncTask.虽然我在循环时不确定......
我想在Swing中创建一个新的事件派发线程,但我无法在线找到任何关于如何执行此操作的引用.我通过创建一个新线程并调用Application.run(...)在.NET中完成了这个.有没有人这样做过?在Swing中有可能吗?
仅供参考我之所以这样做,是因为我正在编写一个Eclipse插件,我想弹出一些不是IDE模态的对话框,但它们是我的UI逻辑的模态(阻塞).我可以使用非模态对话框和回调来实现这一点,但这需要使我的代码多线程的开销.如果前者不可能,我会再回到那里.
我在使用F#开发一个简单的应用程序时遇到问题,它只读取所请求的HTML页面的长度.
当您开发UI应用程序时,似乎这样的错误对于VB.NET/C#语言也是类似的.

但我对F#很陌生,并且真的没想象会在F#中解决这个问题.
F#中的源代码:
open System
open System.Net
open Microsoft.FSharp.Control.WebExtensions
open System.Windows.Forms
let form = new Form()
let text = new Label()
let button = new Button()
let urlList = [ "Microsoft.com", "http://www.microsoft.com/"
"MSDN", "http://msdn.microsoft.com/"
"Bing", "http://www.bing.com"
]
let fetchAsync(name, url:string) =
async {
try
let uri = new System.Uri(url)
let webClient = new WebClient()
let! html = webClient.AsyncDownloadString(uri)
text.Text <- String.Format("Read %d characters for %s", html.Length, name)
with
| ex -> printfn "%s" (ex.Message);
}
let runAll() = …Run Code Online (Sandbox Code Playgroud) 当我await使用抛出异常的方法时,try/catch 不会使应用程序免于崩溃。
有一种投掷方法
void CurrentStep.Process(CancellationToken cancellationToken)
{
throw new Exception();
}
Run Code Online (Sandbox Code Playgroud)
它是通过以下方式从 UI 线程调用的:ICommand.Execute()
ProcessCurrentStepCommand = AsyncCommandFactory.Create(async cancellationToken =>
{
try
{
await Task.Run(() => CurrentStep.Process(cancellationToken));
}
catch {}
CurrentStep = CurrentStep.NextStepViewModel;
});
Run Code Online (Sandbox Code Playgroud)
ProcessCurrentStepCommand绑定到 UI 上的按钮。当我单击按钮时,我的应用程序崩溃了。我觉得在 UI 线程上抛出异常存在一个普遍的问题,但同时我不明白为什么 catch 块不能让我免于异常。
我现在找到了唯一适合我的方法:
await Task.Factory.StartNew(
action: () => CurrentStep.Process(cancellationToken),
creationOptions: TaskCreationOptions.LongRunning);
Run Code Online (Sandbox Code Playgroud)
但看起来很丑。如果我将来忘记了我想用这段代码做什么,我可能会认为我需要清理它,并因某些异常而导致整个应用程序崩溃而陷入麻烦。
当处于调试模式时,一切都表现良好。
调用堆栈:
UI.exe !UI.Steps.ViewModels.SvmConnectionViewModel.Process(System.Threading.CancellationToken CancellationToken)
UI.exe !UI.MainViewModel..ctor.AnonymousMethod__1() 第 18 行 mscorlib.dll !System.Threading.Tasks.Task.InnerInvoke ()第2911行 mscorlib.dll!System.Threading.Tasks.Task.Execute()第2523行 mscorlib.dll!System.Threading.Tasks.Task.ExecutionContextCallback(object obj)第2888行 mscorlib.dll!System.Threading.ExecutionContext。 RunInternal(System.Threading.ExecutionContextexecutionContext,System.Threading.ContextCallback回调,对象状态,布尔保留SyncCtx)第581行
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContextexecutionContext,System.Threading.ContextCallback回调,对象状态,boolserveSyncCtx)第531行
mscorlib.dll …
我亲眼目睹了onBackpressureBuffer的奇怪行为,我不确定它是一个有效的行为还是一个bug.
我有一个tcp调用,以一定的速率发出项目(使用流和inputStream,但只是为了一些信息)
最重要的是,我创建了一个使用create的observable,每次准备就会发出一个项目.
我们称之为message().
然后我这样做:
messages()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({//do some work});
Run Code Online (Sandbox Code Playgroud)
我注意到使用很少抛出MissingBackPressureException的分析工具,所以我在调用中添加了onBackpressureBuffer.
如果我在之后添加observeOn:
messages()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.onBackpressureBuffer()
.subscribe({//do some work})
Run Code Online (Sandbox Code Playgroud)
Everyting工作得很好,但这意味着只有在获得UI主线程之后它才会缓冲,所以我更喜欢它是这样的:
messages()
.onBackpressureBuffer()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({//do some work});
Run Code Online (Sandbox Code Playgroud)
事情开始变得奇怪.
我注意到while messages()会继续发出项目,但在某些时候它们将停止发送给订阅者.
更准确地说,正好在16个项目之后,显而易见的是缓冲区将开始持有物品而不会将它们向前传递.
一旦我取消了messages()某种超时机制,它将导致messages()发出onError(),缓冲区将立即发出它保存的所有项目(它们将被处理).
我已经检查过是否是订购太多工作的订户错误但是没有,他已经完成但他仍然没有得到这些物品......
我也尝试request(n)在订阅者中使用该方法,在onNext()完成后请求一个项目,但缓冲区不起作用.
我怀疑Main Android UI Thread的消息系统带有背压导致这个,但我无法解释原因.
谁能解释为什么会这样?这是一个错误还是一个有效的行为?TNX!
很简单的例子:
<StackLayout>
<Button Text="{Binding LoginButtonText}" Clicked="Button_Clicked"></Button>
</StackLayout>
Run Code Online (Sandbox Code Playgroud)
代码背后:
public partial class ItemsPage : ContentPage
{
private ViewModels.ItemsViewModel _viewModel;
public ItemsPage()
{
_viewModel = new ItemsViewModel();
BindingContext = _viewModel;
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
this._viewModel.LoginButtonText = "Start" + DateTime.Now.ToString();
// this loop is just for testing purposes. To demonstrate
// that this loop block UI thread
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 1000; j++)
{
string …Run Code Online (Sandbox Code Playgroud) ui-thread ×10
android ×5
runnable ×2
arraylist ×1
async-await ×1
backpressure ×1
c# ×1
dialog ×1
exception ×1
f# ×1
handler ×1
java ×1
message-pump ×1
modal-dialog ×1
rx-android ×1
rx-java ×1
swing ×1
vb.net ×1
winforms ×1
wpf ×1
xamarin ×1