我一直在网上搜索此内容,并且无法找到真正有效的解决方案。情况如下:我有一个WPF应用程序,我想向用户呈现一个简单的登录表单。尝试使用MVVM,所以我在login命令后面有一个带有以下代码的LoginViewModel:
try
{
WithClient(servfact.GetServiceClient<IAccountService>(), proxy =>
{
principal = proxy.AuthenticateUser(Login, password);
});
Thread.CurrentPrincipal = principal;
}
catch(...) { ... }
&#34; WithClient&#34;是我的viewmodel基类中的一个简短方法,我用它来实例化和处理我的服务代理:
protected void WithClient<T>(T proxy, Action<T> codeToExecute)
{
try { codeToExecute(proxy); }
finally
{
IDisposable toDispose = (proxy as IDisposable);
if(toDispose != null) { toDispose.Dispose(); }
}
}
现在,我的大多数服务都是Async,并且我有一个Asyncient的异步变体,这也很好用:
protected async Task WithClientAsync<T>(T proxy, Func<T, Task> codeToExecute)
{
try { await codeToExecute(proxy); }
finally
{
IDisposable toDispose = (proxy as IDisposable);
if(toDispose != null) { toDispose.Dispose(); }
}
}
每当我也想异步登录时,麻烦就开始了。显然,我不希望UI在我登录时冻结(或者访问任何WCF服务)。这本身工作正常,但问题出在我设置CurrentPrincipal的代码段中。你们大多数人可能都很熟悉这个问题:它似乎设置得很好。然后在我的程序中,我想使用CurrentPrincipal(在客户端或者将用户登录到messageheader中的WCF服务),但它似乎被重置为标准的GenericPrincipal。当我将登录恢复为同步时,CurrentPrincipal就可以了。简而言之:如何在异步代码中设置主体,让它在以后持续存在,而不是恢复到标准主体?
答案 0 :(得分:1)
// SOURCE: http://stackoverflow.com/questions/39302814/mediastream-capture-canvas-and-audio-simultaneously#39302994
var cStream,
aStream,
recorder,
chunks = [],
canvasEl = document.createElement('canvas');
canvasEl.width = 400;
canvasEl.height = 400;
document.body.appendChild(canvasEl);
/*
create and run external video
*/
var videoEl = document.createElement('video');
videoEl.crossOrigin = 'anonymous';
videoEl.src = 'https://dl.dropboxusercontent.com/s/bch2j17v6ny4ako/movie720p.mp4';
videoEl.play();
videoEl.addEventListener('play', function(){
var audioCtx = new AudioContext();
var dest = audioCtx.createMediaStreamDestination();
aStream = dest.stream;
var sourceNode = audioCtx.createMediaElementSource(this);
console.log('connected audio');
sourceNode.connect(dest);
// output to our headphones
sourceNode.connect(audioCtx.destination)
var canvasCtx = canvasEl.getContext('2d');
console.log('play video in canvas');
draw(this, canvasCtx);
startRecording();
setTimeout(() => {
stopRecording();
}, 10000)
}, false);
function exportStream(e) {
console.log('exportStream', chunks.length);
if (chunks.length) {
var blob = new Blob(chunks),
videoURL = URL.createObjectURL(blob),
resultVideoEl = document.createElement('video');
resultVideoEl.controls = true;
resultVideoEl.src = videoURL;
resultVideoEl.onend = function() {
URL.revokeObjectURL(videoURL);
}
document.body.insertBefore(resultVideoEl, canvasEl);
} else {
document.body.insertBefore(
document.createTextNode('no data saved'), canvasEl);
}
}
function saveChunks(e) {
console.log('save chunks', e.data.size);
e.data.size && chunks.push(e.data);
}
function stopRecording() {
console.log('STOP RECORDING');
videoEl.pause();
recorder.stop();
}
function startRecording() {
console.log('START RECORDING');
cStream = canvasEl.captureStream(30);
cStream.addTrack(aStream.getAudioTracks()[0]);
recorder = new MediaRecorder(cStream);
recorder.start();
// =============================================
// THIS PART IS NOT FIRED WHEN RUN IN BACKGROUND
// and final chunks is always an empty array.
// =============================================
recorder.ondataavailable = saveChunks;
recorder.onstop = exportStream;
}
function draw(v,ctx) {
if(videoEl.paused || videoEl.ended) return false;
// here I'm cropping the video frames and taking only 400 by 400
// square shifted by 100, 100 vector
ctx.drawImage(v, 100, 100, 400, 400, 0, 0, 400,400);
setTimeout(draw,20,v,ctx);
}
所以我在登录后设置了它。我想问题是我在另一个线程中设置了主体,当我离开时它就丢失了?