我正在开发我公司的一个项目,他们Dispatcher.Invoke()在很多地方使用。如果我使用BeginInvokeInvoke 而不是 Invoke,那么Synchronisation线程之间工作正常,但在 Invoke 的情况下,应用程序会冻结,甚至不进入委托方法的执行。有谁知道为什么会这样?
任何答案将不胜感激。
Invoke项目中使用的示例代码:
Dispatcher.Invoke(DispatcherPriority.Send,
new DelegateMethod(MethodtoExecute));
private delegate void DelegateMethod();
void MethodtoExecute()
{
try
{
}
catch (Exception /*ex*/)
{
}
finally
{
}
}
Run Code Online (Sandbox Code Playgroud) 当渲染操作处于活动状态时,应用程序窗口会阻塞。即当设置了 ContentControl 的 Content 属性时。绘制一个用户控件,它是内容的 DataTemplate。冻结持续 5 到 10 秒,具体取决于所使用的 PC。
这个用户控件并不太复杂(大约 250 个简单控件 - 图像、文本框、文本块、按钮等)。布局远非完美,我没有写它,我既没有时间,也不想优化布局,因为问题最多可以减少。
我能够完成的最好的事情是将控件包装在一个“容器”中,该容器能够在 ui/app 窗口冻结之前绘制加载动画并显示繁忙的光标。我在下面给出了一个完整的代码清单。
我在代码中注释了“冻结从此处开始”,位于包装器自定义控件代码中问题的底部。这就是 WPF 渲染引擎开始绘制用户控件(即其中的网格)的时候。
我经常使用我最喜欢的搜索引擎,我了解到 WPF 有一个特殊的“渲染”线程,它与 UI 线程是分开的。
其他的是在冻结时隐藏应用程序窗口并在此期间显示“加载”动画窗口(或此期间的某些衍生物),鉴于下面的代码,这很容易但很荒谬 - 有没有办法减轻这种情况?
这是代码,首先是用例:
<!-- while I am being rendered, I block the UI thread. -->
<UserControl x:Class="MyUserControl"
xmlns:loading="clr-namespace:Common.UI.Controls.Loading;assembly=Common.UI.Controls">
<loading:VisualElementContainer>
<loading:VisualElementContainer.VisualElement>
<Grid>
<!-- some 500 lines of using other controls with binding, templates, resources, etc..
for the same effect try having a canvas with maaany rectangles..-->
</Grid>
</loading:VisualElementContainer.VisualElement>
</loading:VisualElementContainer>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
包装器自定义控件布局:
<Style TargetType="{x:Type …Run Code Online (Sandbox Code Playgroud) 有人可以从实际角度解释一下 Kotlin CoroutineExecutorCoroutineDispatcher和Kotlin Coroutine 之间的区别,即在哪些场景下使用一个协程来对抗另一个协程?CoroutineDispatcher
到目前为止,我一直在使用Dispatchers,但是(据我所知)它不能给我一个后台线程。这就是我使用的原因newSingleThreadExecutor()。
但我注意到的是,我的主进程在使用ExecutorCoroutineDispatcher(1)时永远不会结束( CoroutineDispatcher它按预期完成(2))。经过一番调查后,我似乎应该运行方法close()来ExecutorCoroutineDispatcher完成主流程(3)。由于 CoroutineDispatcher您不必这样做,因此它甚至没有方法close()(4)。是CoroutineDispatcher自动关闭的吗?为什么我们有 for 的关闭流程 ExecutorCoroutineDispatcher,但没有 for CoroutineDispatcher?
下面是我用于测试的代码:
fun main() = runBlocking<Unit> {
val dispatcher1 = Executors.newSingleThreadExecutor().asCoroutineDispatcher() // (1) <-- main process runs indefinitely w/o closing dispatcher1 (3)
val dispatcher2 = Dispatchers.Unconfined // (2)
println("Start")
launch(dispatcher1) {
println("Child")
delay(1000)
printInfo(coroutineContext, this)
}.join()
println("End")
dispatcher1.close() // (3) <-- need to close dispatcher1 for …Run Code Online (Sandbox Code Playgroud) 我想在 Android 中测试以下非常常见的用例作为仪器测试:
这是我的 Viewmodel 中的函数:
fun fetch() {
_loading.value = true //loading is shown
viewModelScope.launch {
val results = fetchUseCase() //suspend function
_result.postValue(results)
_loading.postValue(false) //loading is not displayed
}
}
Run Code Online (Sandbox Code Playgroud)
@HiltAndroidTest
@UninstallModules(CoroutinesDispatcherModule::class)
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTestJunit4Deprecated {
@get:Rule
var hiltRule = HiltAndroidRule(this)
@ExperimentalCoroutinesApi
@get:Rule
var mainCoroutineRule = MainCoroutineRule()
@Before
fun setup() {
ActivityScenario.launch(HomeScreenActivity::class.java)
}
@ExperimentalCoroutinesApi
@Test
fun fetchTest() {
//pausing the long running tasks
mainCoroutineRule.pauseDispatcher()
//When clicking the …Run Code Online (Sandbox Code Playgroud) 我知道这个问题之前已经被问过了,但我已经阅读了几个没有帮助我的答案.
我有一个ComboBox需要从数据库中获取与选择相关的一些信息(可能是丢失焦点,在滚动期间停止一千次调用).此信息仅供显示,而不是关键,因此获得后台线程/任务听起来就像是完美的解决方案.它确实需要几秒钟,因为它从一些非常大的表中得到计数.用户应该可以自由地继续执行其他任务,因为这些信息实际上仅用于显示/参考.
这个问题主张使用后台工作者,但这个解决方案有两个问题.1)在工作人员已经运行时更改选择会引入问题.您可以不是第二次启动它,这意味着当它返回时它不再显示新选择的有效信息,或者尝试取消它(这并不总是有效).2)由于某些原因我无法解释,实际访问后台工作程序数据库的方法如果方法在Model中比在ViewModel中返回的速度慢,我认为它不属于ViewModel.我真的不知道为什么.
这个问题有几个选票,但OP的问题措辞非常糟糕,所选答案只是说"是的,应该有效".
这个问题的方法看起来很有希望,但链接的视频是一个小时(我看了整个事情),并且仅在10-15秒内触及调度员而没有解释它.如果有人链接到更深入地介绍此方法的文章,那就更好了.
线程池,正如这里建议的那样,它可能是最好的方法,因为多个查询请求只是排队,而不是导致已经运行的错误.但是,它没有解释如何使用线程池,而是链接到MSDN文章.如果有人链接到更深入地介绍这种方法的文章,那将是理想的,因为它似乎是更好的解决方案(当然,我可能是错的).
我真的试图对这个进行研究,但大多数答案只是告诉你使用什么方法,而不是如何使用它.我真的在寻找"操作方法".
在回调方法中,我试图获取textBox的text属性,如下所示:
string postData = tbSendBox.Text;
Run Code Online (Sandbox Code Playgroud)
但是因为它没有在UI线程上执行,所以它给了我一个跨线程的异常.
我想要这样的东西:
Dispatcher.BeginInvoke(() =>
{
string postData = tbSendBox.Text;
});
Run Code Online (Sandbox Code Playgroud)
但这是异步运行的.同步版本是:
Dispatcher.Invoke(() =>
{
string postData = tbSendBox.Text;
});
Run Code Online (Sandbox Code Playgroud)
但是Windows Phone不存在Dispatcher.Invoke().有没有相当的东西?有不同的方法吗?
这是整个功能:
public void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the operation
Stream postStream = request.EndGetRequestStream(asynchronousResult);
string postData = tbSendBox.Text;
// Convert the string into a byte array.
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Write to the request stream.
postStream.Write(byteArray, 0, postData.Length);
postStream.Close();
// Start the asynchronous operation to get the response
request.BeginGetResponse(new …Run Code Online (Sandbox Code Playgroud) 为什么我的DispatcherTimer不能与Windows服务一起使用.
我想要使用DispatcherTimer检查Windows服务许可证背后的目的
public OIMService()
{
InitializeComponent();
_dispatcherTimer = new DispatcherTimer();
if (!System.Diagnostics.EventLog.SourceExists("OIM_Log"))
{
EventLog.CreateEventSource("OIM_Log", "OIMLog");
}
EventLog.Source = "OIM_Log";
EventLog.Log = "OIMLog";
_helpers = new ValidationHelpers();
StartTimer();
}
protected override void OnStart(string[] args)
{
System.Diagnostics.Debugger.Launch();
if (_helpers.IsValid())
{
ConfigureServer();
StartTimer();
}
else
{
this.Stop();
}
}
private void StartTimer()
{
const int time = 10;
_dispatcherTimer.Tick += new EventHandler(DispatcherTimerTick);
_dispatcherTimer.Interval = new TimeSpan(0, 0, Convert.ToInt32(time));
_dispatcherTimer.IsEnabled = true;
_dispatcherTimer.Start();
}
private void DispatcherTimerTick(object sender, EventArgs e)
{
EventLog.WriteEntry("test test test …Run Code Online (Sandbox Code Playgroud) 如果从多个后台线程访问,是否需要同步对Dispatcher.Invoke的调用?
我知道Dispatcher.BeginInvoke会自动同步对silverlight app的调用(http://msdn.microsoft.com/en-us/library/z8chs7ft(v=vs.95).aspx)
对于wpf应用程序也是如此,或者我应该取消注释下面的lock语句.
public MainWindow()
{
InitializeComponent();
Dispatcher.BeginInvoke(new Action(() =>
{
const int MAX_NR_THREADS = 1000;
for (int i = 0; i < MAX_NR_THREADS; ++i)
{
int j = i+1;
new Thread(()=>ThreadMethod(j)).Start();
}
}));
}
private void ThreadMethod(int threadId)
{
const int ONE_MILLION = 1000000;
for (int i = 0; i < ONE_MILLION/threadId; ++i)
{
//lock(lockObj)
//{
this.Dispatcher.Invoke(new Action(() =>
{
int sum = 0;
for (int j = 0; j < ONE_MILLION/10000; ++j)
{
sum += …Run Code Online (Sandbox Code Playgroud) 我正在从一个wpf项目转移到winforms项目的方法.
除了这一部分之外的所有内容都没有问题:
private void ServerProcErrorDataReceived(object sender, DataReceivedEventArgs e)
{
// You have to do this through the Dispatcher because this method is called by a different Thread
Dispatcher.Invoke(new Action(() =>
{
richTextBox_Console.Text += e.Data + Environment.NewLine;
richTextBox_Console.SelectionStart = richTextBox_Console.Text.Length;
richTextBox_Console.ScrollToCaret();
ParseServerInput(e.Data);
}));
}
Run Code Online (Sandbox Code Playgroud)
我不知道如何转换Dispatcher为winforms.
谁能帮我吗?
我正在使用此代码在单独的线程中运行ProgressBar。
ProgresBarForm viewer = new ProgressBarForm("Wait");
Thread viewerThread = new Thread(delegate()
{
viewer = new ProgressBarForm("Wait");
viewer.Show();
System.Windows.Threading.Dispatcher.Run();
});
viewerThread.SetApartmentState(ApartmentState.STA); // needs to be STA or throws exception
viewerThread.Start();
Run Code Online (Sandbox Code Playgroud)
然后,我要进行一些长时间的操作,完成后,我将调用以下代码:
viewer.BeginInvoke(new Action(() => window.Close()));
Run Code Online (Sandbox Code Playgroud)
并且它确实运行良好,但是当我关闭窗口调试器时,它并未停止。在VS 2012中,我单击“全部中断”按钮,并且该程序挂在了网上
System.Windows.Threading.Dispatcher.Run();
Run Code Online (Sandbox Code Playgroud)
如何关闭此调度程序以退出程序?
预先感谢您的所有回复。
dispatcher ×10
c# ×6
wpf ×5
android ×1
asynchronous ×1
coroutine ×1
delegates ×1
executor ×1
invoke ×1
kotlin ×1
renderer ×1
rendering ×1
synchronize ×1
threadpool ×1
ui-testing ×1
winforms ×1